简体   繁体   中英

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?

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM