Ozgur
Ozgur

Reputation: 3766

Spring Security - when to clear SecurityContextHolder

I have a controller and I'm returning user info from that controller:

@RequestMapping(method = RequestMethod.GET)
Object getUserInfo() {
    return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}

I have created custom token based authentication using OncePerRequestFilter:

package gbyf;

import gbyf.token.Token;
import gbyf.token.TokenRepository;
import gbyf.user.User;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TokenAuthenticationFilter extends OncePerRequestFilter {

    private final TokenRepository tokenRepository;

    TokenAuthenticationFilter(TokenRepository tokenRepository) {
        this.tokenRepository = tokenRepository;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

        String tokenString = request.getHeader("token");

        if(tokenString == null) {
            // user is not authenticated, continue to filter
            chain.doFilter(request, response);
            return;
        }

        Token token = tokenRepository.findTokenByTokenValue(tokenString);

        if(token == null) {
            System.out.println("=====doFilterInternal()==== token is null, not authenticated");
        } else {

            System.out.println("=====doFilterInternal()==== token is NOT null");
            User user = token.getUser();

            if(user != null) {
                Authentication auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(auth);
                System.out.println("=====doFilterInternal()==== authenticated user");
            }
        }

        super.doFilter(request, response, chain);
    }

}

When I sent correct token parameter that found in database, it correctly authenticates the user. But with another wrong token request, server still sends old user authentication principals. Shouldn't SecurityContextHolder flush the authentication detail after request is done.

What can be the problem?

Upvotes: 1

Views: 5741

Answers (1)

Leffchik
Leffchik

Reputation: 2030

Are you using browser to call the API? If so, then I think session is being created for your user and being tracked via cookies. Try to use stateless session creation policy:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

Upvotes: 12

Related Questions