记一次关于 SpringSecurity SecurityContext生命周期的理解
众所周知 SpringSecurity 将用户认证成功后的信息存放在 SecurityContext中,通过SecurityContextHolder.getContext() 可以在任何地方获得SecurityContext从而获得用户信息,SecurityContext 存在一个请求线程中及 ThreadLocal ,当请求结束后线程关闭SecurityContext 随之消失及在下次请求中无法获得上次请求的用户信息
附源码:
final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<>();
@Override
public void clearContext() {
contextHolder.remove();
}
@Override
public SecurityContext getContext() {
SecurityContext ctx = contextHolder.get();
if (ctx == null) {
ctx = createEmptyContext();
contextHolder.set(ctx);
}
return ctx;
}
@Override
public void setContext(SecurityContext context) {
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");
contextHolder.set(context);
}
@Override
public SecurityContext createEmptyContext() {
return new SecurityContextImpl();
}
}
然而在最近的使用中发现,当第一次请求结束后,发起新的请求,仍然可以获得上次请求保存的用户信息。此时就有点疑惑。
于是猜想SecurityContext的存储是否和Session有关,经验证确实如此,请求结束后SecurityContext 会放入 Session ,当下次访问时 SecurityContext 又会被取出放入重新放入SecurityContextHolder中。
验证思路:请求会根据Cookie查询Session,于是在新的新请求中删除Cookie 发现之前请求的SecurityContext 就无法被获取到了。
查阅文档后,确实如此.