使用Spring Security时,SecurityContext在请求之间是否共享?

10
我在使用基于无状态令牌的身份验证时,发现了一些奇怪的行为。这个rest API是使用Spring Boot编写的。客户端在每个请求中都会包含一个JWT令牌,并且我编写了一个自定义过滤器来扩展GenericFilterBean,根据令牌中的声明添加Authentication对象到安全上下文中,方法如下:
SecurityContextHolder.getContext().setAuthentication(authentication);

在处理请求后,通过执行以下操作来清除上下文:

SecurityContextHolder.getContext().setAuthentication(null);

然而,当我开发的简单应用执行一系列操作时,有时会发现安全上下文没有被正确设置 - 对于已提供令牌的请求,有时为null。过滤器被正确调用,setAuthencation()也被调用,但请求无法通过身份验证,并抛出403拒绝访问。
如果我明确关闭任何http会话管理,将会话创建策略设置为STATELESS,则这种行为停止。
这里可能发生了什么?安全上下文在处理请求的线程之间共享吗?

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - randominstanceOfLivingThing
1个回答

4
根据官方文档,似乎可以共享上下文。具体请参考此处: http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html 在单个会话中接收并发请求的应用程序中,同一个SecurityContext实例将在线程之间共享。即使使用ThreadLocal,每个线程从HttpSession检索到的都是同一个实例。如果您希望暂时更改线程运行的上下文,则会产生影响。如果只是使用SecurityContextHolder.getContext(),并在返回的上下文对象上调用setAuthentication(anAuthentication),则所有共享同一SecurityContext实例的并发线程中的Authentication对象都将更改。您可以自定义SecurityContextPersistenceFilter的行为,以为每个请求创建一个全新的SecurityContext,防止一个线程中的更改影响另一个线程。或者,您可以在暂时更改上下文的点上创建一个新实例。方法SecurityContextHolder.createEmptyContext()始终返回一个新的上下文实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接