升级到Spring-Security 5.7.0 SecurityContextPersistenceFilter未调用



随着WebSecurityConfigurerAdapter在spring -security 5.7.0中被弃用,我们正试图迁移到配置securityFilterChain的新方法,但在这样做时,我注意到在spring调试日志中没有调用SecurityContextPersistenceFilter。因此,当使用requestPostProcessor测试控制器时,当请求被验证时,requestPostProcessor中的身份验证集不会应用于HttpSession。

版本升级日志

[main] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - Created HttpSession as SecurityContext is non-default
[main] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - Stored SecurityContextImpl [Authentication=TestAuthenticationToken [Principal=ApiUser [Username=USER, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[placeholder]], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[]]] to HttpSession [org.springframework.mock.web.MockHttpSession@153d14e3]
[main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - POST "/v1/api_path”, parameters={}
[main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.xyz.Controller#controllerMethod(String, List)

版本升级前的日志

HttpSession as SecurityContext is non-default
[main] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - Stored SecurityContextImpl [Authentication=TestAuthenticationToken [Principal=ApiUser [Username=USERNAME, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[placeholder]], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[]]] to HttpSession [org.springframework.mock.web.MockHttpSession@d641499]
[main] DEBUG org.springframework.security.web.FilterChainProxy - Securing POST /v1/api_path
[main] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - Retrieved SecurityContextImpl [Authentication=TestAuthenticationToken [Principal=ApiUser [Username=USERNAME, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[placeholder]], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[]]]
[main] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - Set SecurityContextHolder to SecurityContextImpl [Authentication=TestAuthenticationToken [Principal=ApiUser [Username=USERNAME, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[placeholder]], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[]]]
[main] DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Authorized filter invocation [POST /v1/api_path] with attributes [authenticated]
[main] DEBUG org.springframework.security.web.FilterChainProxy - Secured POST /v1/api_path
[main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - POST "/v1/api”_path, parameters={}
[main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.Controller#ControllerMethod(String, List)

下面是对SecurityConfig所做的代码更改新代码

/**
* Configure in memory authentication with the default username/password.
* @return InMemoryUserDetailsManager {@link InMemoryUserDetailsManager}
*/
@Bean
public InMemoryUserDetailsManager configureAuthentication() {
final UserDetails userDetails = new User(DEFAULT_USERNAME, DEFAULT_PASSWORD, authorities(DEFAULT_ROLES));
return new InMemoryUserDetailsManager(userDetails);
}
/**
* Security Filter chain for Http requests.
* @param http HttpSecurity
* @return SecurityFilterChain for Http requests
*/
@Bean
public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
http.authorizeRequests(auth ->
auth.anyRequest().authenticated())
.httpBasic()
.and()
.csrf().disable();
return http.build();
}
/**
* Set the default ignore everything on the security context.
* @return WebSecurityCustomizer - used to customize WebSecurity
*/
@Bean
public WebSecurityCustomizer ignoringCustomizer() {
return web -> web.ignoring().antMatchers("/**");
}

旧代码

@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser(DEFAULT_USERNAME)
.password(DEFAULT_PASSWORD)
.roles(DEFAULT_ROLES.toArray(new String[0]));
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
/**
* Set the default ignore everything on the security context.
*
* @param web {@link WebSecurity}.
*/
protected static void setIgnoreEverything(final WebSecurity web) {
web.ignoring().antMatchers("/**");
}

在调试中意识到遗留代码中存在重复的安全过滤器链,但是它们的执行顺序被颠倒了,因此带有antpattern/**的securityfilterchain首先被执行,因此绕过了securityContextpersistencefilter。解决方案是删除/** antpattern,因为它没有任何用途。

最新更新