Reputation: 4830
I write application which use Spring Security. Below I wrote my TokenFilter and WebSecurityConfig. My question is how long SecurityContext does contain logged users? Next question: is my security configuration session stateless or no? Is SecurityContext replacment for Session?
Does my application fulfill the stateless principle?
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);
}
}
And Security Config:
@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();
}
}
Upvotes: 0
Views: 792
Reputation: 11835
SecurityContext
is only used to access Authentication
instance.
SecurityContext
may be stored between your requests. This logic (storing and then restoring for new requests) is implemented in SecurityContextPersistenceFilter
which, in turn, delegates this storage logic to SecurityContextRepository
.
When you use SessionCreationPolicy.STATELESS
, NullSecurityContextRepository
is used (it is an implementation of SecurityContextRepository
); it does NOT actually store SecurityContext
anywhere, and it always 'restores' a fresh (empty) SecurityContext
.
SessionCreationPolicy.STATELESS
also forbids Spring Security to create http session in any of beans which form its machinery.
So when you use SessionCreationPolicy.STATELESS
, the session is never created, and it is certainly not used to store SecurityContext
. Each your request will have a fresh security context (with no Authentication
in it), so each your request will perform a full-blown authentication.
Upvotes: 4