繁体   English   中英

Spring Security-何时清除SecurityContextHolder

[英]Spring Security - when to clear SecurityContextHolder

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

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

我已经使用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);
    }

}

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

可能是什么问题?

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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