【问题标题】:Spring Boot - @PreAuthorize does not work in testSpring Boot - @PreAuthorize 在测试中不起作用
【发布时间】:2018-01-01 12:37:34
【问题描述】:

我有这样的控制器

@RestController
@RequestMapping(value="/test")
@PreAuthorize("hasRole('ADMIN')")
public class TestController
{

    @RequestMapping( method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> test ()
    {

        return ResponseEntity.ok("test");
    }

}

我尝试编写单元测试来测试访问此控制器方法的权限。

这是我的测试

@RunWith(SpringRunner.class)
@ContextConfiguration
 @WebMvcTest(value = TestController.class)
public class AUnitTest
{

    @Autowired
    private MockMvc mockMvc;

    private final String url = "/test";

    @Test
    @WithMockUser(roles="ADMIN")
    public void testAdminUser() throws Exception
    {
        RequestBuilder requestBuilder = MockMvcRequestBuilders.get(this.url );
        MvcResult result = mockMvc.perform(requestBuilder).andReturn();
        assertEquals(HttpStatus.OK.value(), result.getResponse().getStatus());
    }

}

当我从 @WithMockUser 中删除角色并将其留空时,默认情况下它将具有角色 USER,然后测试通过。 当我设置角色 USER 和 ADMIN 时,它也会因为 USER 角色而通过。 但是每当我将角色设置为 ADMIN 时,它都会失败,即使我设置该用户需要具有 ADMIN 角色才能访问控制器。

我尝试设置用户名、密码、Spring Security Docs 等所有内容。

我错过了什么吗?

【问题讨论】:

  • 很奇怪。对我有用,就像你拥有它一样,除了我有 @WebIntegrationTest 而不是 WebMvcTest 并且我正在运行 SpringJUnit4ClassRunner.class
  • SpringRunnerSpringJUnit4ClassRunner 的别名。因为不推荐使用@WebIntegrationTest,所以我尝试使用@SpringBootTest。但后来我在自动装配MockMvc 时遇到问题。然后我尝试使用mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build(); 创建mockMvc,但得到了相同的结果。因为我正在写单元测试,我是否需要检查安全性并将其留给集成测试?
  • 我们也使用MockMvcBuilders.webAppContextSetup(context).apply(springSecu‌​rity()).build(),它正在工作。测试代码之外一定有什么东西在阻止它为你工作。
  • @Boris 在使用@SpringBootTest 时,您可以在类上使用@AutoConfigureMockMvc,然后自动连接MockMvc

标签: java spring spring-mvc spring-security


【解决方案1】:

尝试将@EnableGlobalMethodSecurity(prePostEnabled = true)添加到测试类。

或者像这样添加配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class Config {
    ...
}

【讨论】:

  • 我进行了广泛的搜索,这是唯一有效的解决方案!谢谢!如果直接使用@EnableGlobalMethodSecurity(prePostEnabled = true),会调用Spring的权限评估器。相反,您需要将扩展​​ GlobalMethodSecurityConfiguration 并指向您的自定义权限评估器实现的配置类添加到测试的 ContextConfiguration 注释中。否则,Spring 将拒绝所有请求。
  • @bizyb: 或者只是在您的测试配置类中添加@EnableGlobalMethodSecurity(prePostEnabled = true),自定义权限评估器声明为@Bean。 AFAIK,这是最短的解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-01-05
  • 2020-09-24
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 2019-01-29
  • 2017-04-15
  • 2014-07-05
相关资源
最近更新 更多