夢のの*_*のの夢 1 spring-mvc spring-security spring-boot
这是我的设置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup", "/health").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login")
.permitAll()
...
Run Code Online (Sandbox Code Playgroud)
测试类:
@ExtendWith(SpringExtension.class)
@WebMvcTest
@WithMockUser
class ApiControllerTest {
...
Run Code Online (Sandbox Code Playgroud)
@WithMockUser
使用以下 GET 可以正常工作:
mockMvc.perform(get("/api/book/{id}", id))
.andExpect(status().isOk())
...
Run Code Online (Sandbox Code Playgroud)
但不是 POST:
mockMvc.perform(post("/api/book")
.contentType(MediaType.APPLICATION_JSON)
.content(payload))
.andExpect(status().isCreated())
...
Run Code Online (Sandbox Code Playgroud)
当我查看 MockHttpServletResponse 的日志时,我注意到响应重定向到登录页面,如下所示:
MockHttpServletResponse:
Status = 302
Error message = null
Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY", Location:"/login"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = /login
Cookies = []
Run Code Online (Sandbox Code Playgroud)
我知道这@WithMockUser
为模拟用户身份验证提供了大量的默认值。为什么它不适用于有状态的 API 请求?
默认情况下,Spring Security 保护您免受跨站点请求伪造。
如果你不想要它,你必须在你的配置中主动禁用它。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
...
Run Code Online (Sandbox Code Playgroud)
幸运的是你没有这样做,这样做是不安全的。
但因此,您每次执行 a 时都需要提供 csrf 令牌POST
,在您的测试中也是如此!
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
...
mockMvc.perform(post("/api/book")
.with(csrf()) // <--- missing in your test
.contentType(MediaType.APPLICATION_JSON)
.content(payload))
.andExpect(status().isCreated());
Run Code Online (Sandbox Code Playgroud)
现在你的测试应该可以工作了。
归档时间: |
|
查看次数: |
454 次 |
最近记录: |