user
user

Reputation: 4830

REST - Creating session

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

Answers (1)

Roman Puchkovskiy
Roman Puchkovskiy

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

Related Questions