Spring Boot 2、Spring Security 5 和 @WithMockUser

Posted

技术标签:

【中文标题】Spring Boot 2、Spring Security 5 和 @WithMockUser【英文标题】:Spring Boot 2, Spring Security 5 and @WithMockUser 【发布时间】:2019-03-07 08:00:44 【问题描述】:

由于我从 1.x 迁移到 Spring Boot 2.0.5,无意禁用安全性,我无法让测试角色在模拟 MVC 测试中工作:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ApplicationsControllerShould 
    ...
    @Autowired
    private MockMvc mockMvc;
    private ObjectMapper mapper = new ObjectMapper();

    @Test
    @WithMockUser(roles = "ADMIN")
    public void handle_CRUD_for_applications() throws Exception 
        Application app = Application.builder()
                .code(APP_CODE).name(APP_NAME)
                .build();
        mockMvc.perform(post("/applications")
                .accept(MediaType.APPLICATION_JSON_UTF8)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(mapper.writeValueAsString(app)))
                .andExpect(authenticated())
                .andExpect(status().isOk());    // failure 403!
...

我的控制器端点甚至没有受到保护!

@RestController
@RequestMapping("/applications")
public class ApplicationsController 
    ...
    @PostMapping
    public Application addApplication(@RequestBody Application application) 
        Assert.isTrue(!applicationsDao.existsById(application.getCode()), "Application code already exists: " + application.getCode());
        return applicationsDao.save(application);
    

所以我在测试中有一个会话(当@WithMockUser 被注释掉时#authenticated 失败)和一个角色(ROLE_ADMIN 在跟踪中可见)但我的请求被拒绝了,我不明白我做了什么错误的。 谢谢你的任何想法!

【问题讨论】:

【参考方案1】:

好的...好的旧 CSRF 东西,然后...

logging.level.org.springframework.security=DEBUG

2018-10-02 10:11:41.285 DEBUG 12992 --- [main] o.s.security.web.csrf.CsrfFilter:为 http://localhost/applications/foo 找到无效的 CSRF 令牌

    Application app = Application.builder()
            .code(APP_CODE).name(APP_NAME)
            .build();
    mockMvc.perform(post("/applications").with(csrf())    // oups...
            .accept(MediaType.APPLICATION_JSON_UTF8)
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .content(mapper.writeValueAsString(app)))
            .andExpect(authenticated())
            .andExpect(status().isOk());    // there we go!

【讨论】:

以上是关于Spring Boot 2、Spring Security 5 和 @WithMockUser的主要内容,如果未能解决你的问题,请参考以下文章

UnsatisfiedDependencyException:创建名为“securityConfig”的 bean 时出错

SpringSecurity基于数据库认证

Spring Boot 2:Spring Boot 2.0新特性

spring boot 2.0之使用spring boot

spring-boot:我可以修复 spring-boot 2 中的下一个错误吗?

Spring boot- Spring Boot特性2