【发布时间】:2019-11-01 05:56:02
【问题描述】:
我有一个 DispatcherServlet,它有一个 URL 映射 /api1,然后是一个带有映射 @GetMapping("/resource1") 的控制器,用于控制器方法。所以基本上我有一个有效的 URL /api1/resource1 应该由提到的控制器处理。
此外,该设置还包含一个 Spring 安全过滤器,该过滤器与请求 /* 匹配,因为它保护了 Spring 未处理的其他 URL(例如 Jersey)。
由 Spring Security Filter 保护的 API 设置如下
protected void configure(HttpSecurity http) throws Exception {
//@formatter:off
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.requestMatchers()
.antMatchers("/api1/**")
.and()
.authorizeRequests()
.antMatchers("/**")
.authenticated()
为了测试,我使用 MockMvc* 支持来设置一个模拟 Web 环境,包括 Spring 安全设置
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build()
我想测试是否应用了安全检查,并且在成功的安全检查时调用了控制器方法。
when:
def result = mvc.perform(
get('/api1/resource1')
.header(HttpHeaders.AUTHORIZATION, "Bearer " + apiToken))
then:
result.andExpect(status().isOk())
上面的代码是基于 Spock 框架和 MockMvc 的东西。 所有的安全检查都通过了,所以 Spring 安全设置完成了,但最终应该调用控制器但失败并出现 404 状态,即资源 - 这是映射的控制器方法 - 未找到。
我确信它会失败,因为模拟设置未包含 /api 调度程序 servlet 映射。为了证明这一假设,我可以将控制器方法映射修改为@GetMapping("/api1/resource1"),测试将产生 HTTP OK (200)。
所以,我的问题是,是否可以在 MockMvc 设置中配置一种 URL 前缀? 有一个限制,代码库没有使用 Spring Boot(未来一段时间也不能使用)!
编辑: 我在测试中添加了以下内容,让所有请求都设置了 servletPath。
static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVars) {
new MockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, uriVars)
.servletPath('/api1')
}
【问题讨论】:
标签: spring-security spring-test-mvc