She*_*men 2 spring spring-security spring-boot spring-session
这是 Spring Boot 3.0.1 版本的问题。这对于 2.7.5 版本来说工作得非常好。
我的应用程序使用 Spring Security 和 JDBC 会话。所以我被X-Auth-Token保存在spring_session我的数据库(PostgreSQL)的表中。当我调用登录控制器方法时,我已经实现了UserDetailsService从数据库中获取用户的接口。
当迁移到新的 Spring Boot 3 版本时,主要的变化发生在WebSecurityConfig类中。以前它是从WebSecurityConfigurerAdapter班级延伸出来的。所以我知道问题出在这堂课的某个地方。
在这里,我复制并粘贴该类的旧版本 2.7.5(工作正常)和新的 3.0.1 版本WebSecurityConfig:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Autowired
UserDetailsService userDetailsService;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private PasswordEncoder passwordEncoder;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.cors()
.and()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/api/usermanager/auth/login").permitAll()
.antMatchers(HttpMethod.GET, "/api/usermanager/image/org/**").permitAll()
.antMatchers("/invalidSession*").anonymous()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.failureHandler(authenticationFailureHandler)
.and()
.sessionManagement()
.sessionFixation()
.migrateSession()
.maximumSessions(1)
.expiredUrl("/sessionExpired.html")
.maxSessionsPreventsLogin(false);
}
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers("/docs/**", "/resources/**", "/static/**");
}
@Bean
public AuthenticationFailureHandler myFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
@Bean
public HttpSessionIdResolver httpSessionStrategy() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("client")
.password(passwordEncoder.encode("Client@Venturi"))
.roles("USER");
var daoAC = new DaoAuthenticationConfigurer(userDetailsService);
daoAC.passwordEncoder(passwordEncoder);
auth.apply(daoAC);
}
}
Run Code Online (Sandbox Code Playgroud)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http,
PasswordEncoder passwordEncoder)
throws Exception {
var daoAC = new DaoAuthenticationConfigurer(userDetailsService);
daoAC.passwordEncoder(passwordEncoder);
var builder = http.getSharedObject(AuthenticationManagerBuilder.class);
builder.apply(daoAC);
return builder.build();
}
private static final String[] AUTH_WHITELIST = {
"/api/usermanager/auth/login"
};
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.and()
.cors()
.and()
.httpBasic()
.and()
.authorizeHttpRequests(
requests -> requests.
requestMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
)
.sessionManagement()
.sessionFixation()
.migrateSession()
.maximumSessions(1)
.expiredUrl("/sessionExpired.html")
.maxSessionsPreventsLogin(false);
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers(HttpMethod.GET,
"/docs/**", "/resources/**", "/static/**"
);
}
@Bean
public AuthenticationFailureHandler myFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
@Bean
public HttpSessionIdResolver httpSessionStrategy() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用上面的身份验证/登录控制器 API 时,我得到表中填充的会话 ID spring_session。但principal_name该表中的 是null。我希望您知道该spring_session表是Spring Session创建的默认表,用于保存会话信息。
在2.7.5版本中,principal_name将保存(用户登录名)。x-auth-token所以在后续的请求中,我可以通过在HTTP请求头中传递 来获取用户。所以我现在的问题是,当我调用上面的控制器 API 时,它principal_name总是null在表中。spring_session
WebSecurityConfig谁能看看我在将类转换为 Spring Boot 版本 3时是否做错了什么?
小智 5
与以前版本的差异是由于此更改:https ://github.com/spring-projects/spring-security/issues/11110
您可以使用旧策略(已弃用)自动保存 SecurityContextHolder 设置:
http.securityContext((securityContext) -> securityContext.requireExplicitSave(false))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1633 次 |
| 最近记录: |