【发布时间】:2021-07-29 03:10:05
【问题描述】:
我正在经历 Spring Security 的不同类实现。我知道我们将 Authentication 对象设置为 SecurityContext ThreadLocal 对象为:
UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
upat.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(upat);
因此,基本上每个线程都有一个单独的 SecurityContext ThreadLocal 对象副本,该对象保存该线程的 Authentication 对象。到这里为止很好。我在我的 SecurityConfiguration 中也将 SessionCreationPolicy 设置为无状态。下面是安全配置:
@Override
protected void configure(HttpSecurity http) throws Exception
{
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
final CorsConfigurer<HttpSecurity> cors = http.csrf().disable().cors().configurationSource(source);
final ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry exp =
cors.and().authorizeRequests();
exp.antMatchers("/getJWTToken/**").permitAll()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/rest/**").authenticated();
exp.and().exceptionHandling()
.authenticationEntryPoint(authEntryPoint())
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
;
// Add a filter to validate the tokens with every request
http.addFilterBefore(authRequestFilter(), UsernamePasswordAuthenticationFilter.class);
}
但是,我对“线程”在这里的含义感到困惑?
- 他们的意思是,单个 HTTP 请求与会话没有任何关系,即对于每个 HTTP 请求,都会有一个新的 ThreadLocal Authentication 对象?
- 或者,它是特定于 HTTP 会话的吗?即对于用户的会话,将只有一个线程,因此只有一个安全上下文?
对于上述两点,我也有这两个疑问。
- 对于上面的1,如果它随着每个请求而改变,那么为什么我们需要在每个请求的线程中检查Authentication对象,如下所示。我的意思是,如果它是一个不同的线程,则不需要这个。它肯定是空的。 (我所指的应用程序中存在以下 if 条件)。
if( SecurityContextHolder.getContext().getAuthentication() == null ) {
if( jwtTokenUtil.validateToken(jwtToken, userObj) )
{
if( userObj == null )
{
response.setStatus(401);
return;
}
else
{
UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(userObj, null,userObj.getAuthorities());
upat.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(upat);
}
}
}
- 对于上述 2,如果我在 Security Config 类中将 SessionCreationPolicy 设置为无状态,则再次没有会话,但不同线程上的请求不同。
我在这里对线程(ThreadLocal SecurityContext)的解释可能是错误的。 需要帮助。
【问题讨论】:
标签: java spring spring-boot spring-security web-applications