Spring Security @WithMockUser似乎不适用于状态更改动词(post,put ..)

时间:2019-11-10 02:37:49

标签: spring-boot spring-mvc spring-security

这是我的设置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/signup", "/health").permitAll()
            .anyRequest().authenticated().and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
...

测试类:

@ExtendWith(SpringExtension.class)
@WebMvcTest
@WithMockUser
class ApiControllerTest {
    ...

@WithMockUser可以在以下GET上正常工作:

mockMvc.perform(get("/api/book/{id}", id))
        .andExpect(status().isOk())
...

但不支持POST:

mockMvc.perform(post("/api/book")
        .contentType(MediaType.APPLICATION_JSON)
        .content(payload))
        .andExpect(status().isCreated())
...

当我查看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 = []

我知道@WithMockUser为模拟用户身份验证提供了大量默认值。为什么它不能用于有状态API请求?

1 个答案:

答案 0 :(得分:0)

默认情况下,Spring Security可以防止跨站点请求伪造。

如果您不想使用它,则必须在配置中主动将其禁用。

#Create game_id which will be used to delete duplicates later
bbattend['game_id'] = bbattend['Team'] + bbattend['Date'].astype(str)
#Create year variable for matching
bbattend['Year'] = bbattend.Date.dt.year

# Create merged table
# Will match all dates of games of team with dates within same year of teams from same-market team 
merged = bbattend.merge(
    bbattend[["Date", "Year", "Team", "Net_Wins", "Win_Per"]],
    how="inner",
    left_on=["Year", "Same_Mkt_Team"],
    right_on=["Year", "Team"],
    suffixes=('', '_Same_Mkt_Team')
)

merged["date_diff"] = (merged.Date - merged.Date_Same_Mkt_Team).dt.days
#Only keep the dates of same-market team that occurred before the date of home team's game
merged = merged[merged['date_diff'] > 0]

#Sort by date_diff so closest dates appear first
merged.sort_values(by='date_diff', inplace = True)

#Only keep first game_id which will include the data of the same-market team for the closest date before the game
merged.drop_duplicates(subset =['game_id'], keep = 'first', inplace = True)

merged

幸运的是,您这样做并不安全。

但是,结果是,每次执行@Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() ... 时都需要提供一个csrf令牌,在测试中也是如此!

POST

现在您的测试应该可以了。