Spring Security-何时清除SecurityContextHolder

Ozg*_*gur 0 java spring spring-security spring-boot

我有一个控制器,并且正在从该控制器返回用户信息:

@RequestMapping(method = RequestMethod.GET)
Object getUserInfo() {
    return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
Run Code Online (Sandbox Code Playgroud)

我使用以下方法创建了基于自定义令牌的身份验证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);
    }

}
Run Code Online (Sandbox Code Playgroud)

当我发送数据库中找到的正确令牌参数时,它会正确验证用户身份。但是对于另一个wrong令牌请求,服务器仍然发送旧的用户身份验证主体。请求完成后,SecurityContextHolder不应刷新身份验证详细信息。

可能是什么问题?

Lef*_*hik 5

您是否正在使用浏览器来调用API?如果是这样,那么我认为正在为您的用户创建会话并通过cookie进行跟踪。尝试使用无状态会话创建策略:

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