Spring Security + Spring-Boot 测试控制器

Posted

技术标签:

【中文标题】Spring Security + Spring-Boot 测试控制器【英文标题】:Spring Security + Spring-Boot Testing Controller 【发布时间】:2018-01-02 08:30:38 【问题描述】:

我正在尝试测试家庭控制器

@RequestMapping("/")
@ResponseBody
String home() 
    return "Hello World!";

我使用 spring security 作为用户名“user”并默认测试为密码,但 @PreAuthorize 不起作用

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@PreAuthorize("hasRole('ADMIN')")
public class HomeControllerTest 

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    @WithMockUser(username = "user", password = "test", roles = "ADMIN")
    public void home() throws Exception 
        String body = this.restTemplate.getForObject("/", String.class);
        assertThat(body).isEqualTo("Hello World!");
    


结果

预期结果:

实际结果:

我错过了什么吗?

【问题讨论】:

你正在调用一个真正的控制器,所以在这里使用@WithMockUser 几乎没用。仅当您直接在控制器上调用 home() 方法时,这才有效。假设您具有用于登录的基本身份验证设置,您应该将凭据与您的请求一起发送。此外,您的测试用例上的 @PreAuthorize 也不会取得任何成果。 【参考方案1】:

尝试将以下内容添加到您的测试类中:

@TestExecutionListeners(mergeMode = MergeMode.MERGE_WITH_DEFAULTS, listeners = 
        WithSecurityContextTestExecutionListener.class
)

如果你没有,还有以下依赖:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
</dependency>

Spring 安全需要一个额外的侦听器,默认情况下测试中不存在,因此您需要通过在 merge 模式下指定 @TestExecutionListeners 注释来告诉 spring 添加它,以便它将当前列出的侦听器与您的侦听器合并想添加 - 在这种情况下WithSecurityContextTestExecutionListener

【讨论】:

谢谢,但它不起作用我收到相同的结果:/ 尝试将ROLE_ADMIN 添加到@WithMockUser 中的roles。 Spring security 默认检查前缀ROLE(但在@PreAuthorize 中保持为ADMIN

以上是关于Spring Security + Spring-Boot 测试控制器的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security:2.4 Getting Spring Security

Spring mvc / security:从spring security中排除登录页面

没有 JSP 的 Spring Security /j_spring_security_check

Spring-Security

Spring Security 登录错误:HTTP 状态 404 - /j_spring_security_check

Spring 框架 4.0 和 Spring security 3.2.4 上的 Spring Security SAML 扩展