Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring security 如何使用H2数据库中的用户预加载Spring Boot集成测试?_Spring Security_Integration Testing_Spring Boot Test_Spring Boot 2 - Fatal编程技术网

Spring security 如何使用H2数据库中的用户预加载Spring Boot集成测试?

Spring security 如何使用H2数据库中的用户预加载Spring Boot集成测试?,spring-security,integration-testing,spring-boot-test,spring-boot-2,Spring Security,Integration Testing,Spring Boot Test,Spring Boot 2,我使用的是SpringBoot2.1。我也在使用H2内存数据库。我已在src/test/resources/data.sql创建了此文件: insert into roles (id, name) values ('1be4965cb4f311eaa2b76a0000c30600', 'USER'); insert into roles (id, name) values ('1be6b2acb4f311eaa2b76a0000c30600', 'ADMIN'); insert into pr

我使用的是SpringBoot2.1。我也在使用H2内存数据库。我已在src/test/resources/data.sql创建了此文件:

insert into roles (id, name) values ('1be4965cb4f311eaa2b76a0000c30600', 'USER');
insert into roles (id, name) values ('1be6b2acb4f311eaa2b76a0000c30600', 'ADMIN');

insert into privileges (id, name) values ('1be4965cb4f311eaa2b76a0000c30600', 'USER');
insert into privileges (id, name) values ('1be6b2acb4f311eaa2b76a0000c30600', 'SUPER_ADMIN');

insert into roles_privileges (role_id, privilege_id) VALUES ('1be4965cb4f311eaa2b76a0000c30600', '1be4965cb4f311eaa2b76a0000c30600');
insert into roles_privileges (role_id, privilege_id) VALUES ('1be6b2acb4f311eaa2b76a0000c30600', '1be6b2acb4f311eaa2b76a0000c30600');

insert into occasions (id, name) values ('97c625b8b63511ea9d386a0000c30600', 'Birthday');

insert into users (id, email, enabled, first_name, last_name, password, token_expired) values ('aa7625b8b63512929d386a0000c30600', 'me@example.com', true, 'lone', 'ranger', 'password', false);

insert into users_roles (user_id, role_id) values ('aa7625b8b63512929d386a0000c30600', '1be6b2acb4f311eaa2b76a0000c30600');
我想创建一个spring引导集成测试来测试以下方法

@RestController
@RequestMapping("/api/cards")
public class CardController {

    @Autowired
    private CardService cardService;
    
    @PostMapping
    @ResponseStatus(code = HttpStatus.CREATED)
    public void create(@RequestBody Card card, @AuthenticationPrincipal User loggedInUser) {
        card.setAuthor(loggedInUser);
        cardService.save(card);
    }
我想在我的数据库中加载一个用户,但我不确定最简单的方法是什么。我尝试了“@WithMockUser”,但没有加载此用户

@SpringBootTest(classes = CardmaniaApplication.class, 
    webEnvironment = WebEnvironment.RANDOM_PORT)
public class CardControllerIntegrationTest {

    @LocalServerPort
    private int port;
    
    @Autowired
    private TestRestTemplate restTemplate;
    
    @Autowired
    private ICardRepository cardRepository;

    @Autowired
    private IUserRepository userRepository;
    
    @Autowired
    private IOccasionRepository occasionRepository;
    
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    
    @Value("${jwt.http.request.header}")
    private String tokenHeader;
    
    @BeforeEach
    void setup() {
        UserDetails user = (UserDetails) userRepository.findAll().get(0);
        final String token = jwtTokenUtil.generateToken(user);
        restTemplate.getRestTemplate().setInterceptors(
                Collections.singletonList((request, body, execution) -> {
                    request.getHeaders()
                            .add(this.tokenHeader, "Bearer " + token);
                    return execution.execute(request, body);
                }));
    }
    
    @Test
    @WithMockUser(authorities = {"ADMIN"})
    void createCard() throws Exception {
        final Card card = new Card();
        final User author = userRepository.findAll().get(0);
        card.setAuthor(author);
        final Occasion occasion = occasionRepository.findAll().get(0);
        card.setOccasion(occasion);
        byte[] image = new byte[] {1, 1, 1, 1};
        card.setImage(image);
        
        ResponseEntity<String> responseEntity = this.restTemplate
                .postForEntity("http://localhost:" + port + "/api/cards", card, String.class);
            assertEquals(201, responseEntity.getStatusCodeValue());

        List<Card> cards = cardRepository.findByOccasion(occasion);
        assertThat(cards.size()).isEqualTo(1);
        final Card cardEntity = cards.get(0);
        assertThat(cardEntity.getImage()).isEqualTo(image);
    }
}
@SpringBootTest(classes=CardmaniaApplication.class,
webEnvironment=webEnvironment.RANDOM\u端口)
公共类CardControllerIntegrationTest{
@本地服务器端口
专用int端口;
@自动连线
私有TestRestTemplate;
@自动连线
专用ICardRepository卡存储库;
@自动连线
专用IUserRepository用户存储库;
@自动连线
私有IOccasionRepository-occasionRepository;
@自动连线
私有JwtTokenUtil JwtTokenUtil;
@值(${jwt.http.request.header}”)
私有字符串令牌头;
@之前
无效设置(){
UserDetails user=(UserDetails)userRepository.findAll().get(0);
最终字符串标记=jwtTokenUtil.generateToken(用户);
restTemplate.getRestTemplate().setInterceptors(
Collections.singletonList((请求、正文、执行)->{
request.getHeaders()
.add(此.tokenHeader,“承载人”+令牌);
返回执行。执行(请求,正文);
}));
}
@试验
@WithMockUser(权限={“ADMIN”})
void createCard()引发异常{
最终卡=新卡();
最终用户作者=userRepository.findAll().get(0);
卡.集作者(作者);
final case=occasionRepository.findAll().get(0);
卡.设置场合(场合);
字节[]图像=新字节[]{1,1,1,1};
设置图像(图像);
ResponseEntity ResponseEntity=this.restTemplate
.postForEntity(”http://localhost:“+port+”/api/cards”,卡片,字符串.class);
assertEquals(201,responseEntity.getStatusCodeValue());
列表卡=cardRepository.findByOccasion(场合);
资产(cards.size()).isEqualTo(1);
最终卡片cardEntity=cards.get(0);
assertThat(cardEntity.getImage()).isEqualTo(image);
}
}

我对spring boot相当陌生,因此不熟悉将用户预加载到我的安全主体中的最简单方法。

此设置当前存在冲突。一方面,您使用
@WithMockUser
SecurityContext
提供模拟用户,另一方面,您为实际身份验证准备有效的JWT令牌

@WithMockUser
通常用于测试中,例如轻松访问受保护的端点,而无需创建具有正确身份验证信息的请求(如JWT或基本身份验证)

因此,您应该选择当前的方法之一:要么模仿用户,要么生成JWT并访问您的端点

您的
@WithMockUser
当前无法工作的原因可能与默认用户名Spring Security picks有关。如果你想在你的数据库中匹配你的用户,考虑配置它:<代码> @使用MoCKUSER(用户名=“YouthUrrError”,角色= {“用户”,“admin”})< /代码>

要进一步调试应用程序,可以临时添加

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

对于端点,您正在测试和调试它,以了解哪个用户现在实际上是
SecurityContext

的一部分。我发现答案是使用“@WithUserDetails”注释

@Test
@WithUserDetails("me@example.com")
void registrationWorksThroughAllLayers() throws Exception {

这将使用实现UserDetailsService的autowired类,并使用带注释的值调用其loadUserByUsername,“me@example.com,在上面的代码中。

是否有任何方法通过注释(无论是通过@WithMockUser还是其他方式)来配置从我的H2数据库中的记录生成的登录用户?例如,“@WithMockUser”似乎不支持ID字段,因此我似乎无法从该字段加载登录的用户ID。我想不会,但您可以不使用注释,使用实际JWT的方法,就像您已经使用的一样,答案是使用“@WithUserDetails(”me@example.com")'. 直到昨天我才知道这个注释。