我编写使用Spring Security的应用程序。下面我写了我的TokenFilter和WebSecurityConfig。 我的问题是SecurityContext包含登录用户的时间有多长? 下一个问题:我的安全配置会话是无状态还是没有? SecurityContext是否替换为Session?
我的申请是否符合无国籍原则?
public class TokenFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private TokenHelper tokenHelper;
private String tokenHeader = "Auth";
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws ServletException, IOException {
final String authToken = httpServletRequest.getHeader(this.tokenHeader);
final String username = tokenHelper.getUsernameFromToken(authToken);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
final UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (tokenHelper.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UnauthorizedHandler unauthorizedHandler;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(this.userDetailsService)
.passwordEncoder(this.passwordEncoder);
}
@Autowired
public BCryptPasswordEncoder passwordEncoder;
@Autowired
public TokenFilter tokenFilter;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.anyRequest().authenticated();
httpSecurity.addFilterBefore(
tokenFilter,
UsernamePasswordAuthenticationFilter.class
);
httpSecurity.headers().cacheControl();
}
}
答案 0 :(得分:1)
2666
9953
2666
9953
1171
2666
1252
2666
1171
1171
9953
1171
2666
1171
仅用于访问SecurityContext
个实例。
Authentication
。这个逻辑(存储然后恢复新请求)在SecurityContext
中实现,然后将此存储逻辑委托给SecurityContextPersistenceFilter
。
当您使用SecurityContextRepository
时,会使用SessionCreationPolicy.STATELESS
(它是NullSecurityContextRepository
的实现);它实际上并不存储SecurityContextRepository
任何地方,它总是'恢复'一个新的(空)SecurityContext
。
SecurityContext
还禁止Spring Security在任何构成其机器的bean中创建http会话。
因此,当您使用SessionCreationPolicy.STATELESS
时,永远不会创建会话,并且肯定不会用于存储SessionCreationPolicy.STATELESS
。您的每个请求都有一个全新的安全上下文(其中没有SecurityContext
),因此您的每个请求都将执行完整的身份验证。