Spring 安全上下文 returns 另一个用户
Spring security context returns another user
我制作了一个 servlet 过滤器来执行自定义身份验证(基于 header 由位于我 tomcat 前面的 apache 设置的 header。如果安全上下文中已经存在身份验证 object,我正在使用它。
但是在某些情况下,身份验证 object 属于另一个用户,而不是发出请求的用户。
我做错了什么?
有没有办法可靠地获得经过身份验证的用户,或者我应该始终在过滤器中进行身份验证?
如果我每次都必须进行身份验证,是否可以创建一个新的身份验证 object (它是我的用户实体的包装器),否则会导致内存泄漏,所以我应该缓存那些 objects?
以下是代码的相关部分:
@Service
public class RemoteAuthenticationFilter extends GenericFilterBean
implements Filter {
@Override
public void doFilter(
final ServletRequest req, final ServletResponse res,
final FilterChain filterChain
) throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest) req;
final SecurityContext context = SecurityContextHolder.getContext();
if (
context.getAuthentication() == null ||
!context.getAuthentication().isAuthenticated()
) {
//creating an Authentication in auth
SecurityContextHolder.getContext().setAuthentication(auth);
} else {
// in this branch context.getAuthentication() sometimes returns another user
}
filterChain.doFilter(req, res);
}
}
这是因为你从来没有清除过SecurityContext
,因为它使用ThreadLocal
来存储认证,如果使用同一个线程处理下一个请求,它仍然保留之前的认证。
我建议您在 chain.doFilter(req, resp)
之后添加 SecurityContextHolder.clearContext()
,去掉 if-else
语句,只为每个请求创建一个新的身份验证。
我制作了一个 servlet 过滤器来执行自定义身份验证(基于 header 由位于我 tomcat 前面的 apache 设置的 header。如果安全上下文中已经存在身份验证 object,我正在使用它。 但是在某些情况下,身份验证 object 属于另一个用户,而不是发出请求的用户。
我做错了什么? 有没有办法可靠地获得经过身份验证的用户,或者我应该始终在过滤器中进行身份验证? 如果我每次都必须进行身份验证,是否可以创建一个新的身份验证 object (它是我的用户实体的包装器),否则会导致内存泄漏,所以我应该缓存那些 objects?
以下是代码的相关部分:
@Service
public class RemoteAuthenticationFilter extends GenericFilterBean
implements Filter {
@Override
public void doFilter(
final ServletRequest req, final ServletResponse res,
final FilterChain filterChain
) throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest) req;
final SecurityContext context = SecurityContextHolder.getContext();
if (
context.getAuthentication() == null ||
!context.getAuthentication().isAuthenticated()
) {
//creating an Authentication in auth
SecurityContextHolder.getContext().setAuthentication(auth);
} else {
// in this branch context.getAuthentication() sometimes returns another user
}
filterChain.doFilter(req, res);
}
}
这是因为你从来没有清除过SecurityContext
,因为它使用ThreadLocal
来存储认证,如果使用同一个线程处理下一个请求,它仍然保留之前的认证。
我建议您在 chain.doFilter(req, resp)
之后添加 SecurityContextHolder.clearContext()
,去掉 if-else
语句,只为每个请求创建一个新的身份验证。