Ric*_*Ric 7 authentication spring-security thread-safety security-context spring-boot
在使用Spring Boot编写的rest API上使用基于无状态令牌的身份验证时,我看到一些奇怪的行为。
客户端在每个请求中都包含一个JWT令牌,我编写的自定义过滤器扩展了GenericFilterBean,它使用以下内容基于令牌中的声明向安全上下文添加了Authentication对象:
SecurityContextHolder.getContext().setAuthentication(authentication);
Run Code Online (Sandbox Code Playgroud)
并通过执行以下操作来清除上下文:
SecurityContextHolder.getContext().setAuthentication(null);
Run Code Online (Sandbox Code Playgroud)
但是,当我开发的简单应用执行一系列操作时,有时会看到安全上下文设置不正确-有时对于提供令牌的请求而言,它为null。正确地调用了过滤器,还调用了setAuthencation(),但是请求未通过身份验证,并抛出403被拒绝。
如果我通过将会话创建策略设置为STATELESS来明确关闭任何http会话管理,则此行为将停止。
有什么想法会在这里发生吗?安全上下文是否以某种方式在处理请求的线程之间共享?
根据此处的官方文档,上下文似乎可以共享: http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html
在单个会话中接收并发请求的应用程序中,同一个 SecurityContext 实例将在线程之间共享。即使使用了 ThreadLocal,它也是从每个线程的 HttpSession 中检索的相同实例。如果您希望临时更改线程运行的上下文,这会产生影响。如果您仅使用 SecurityContextHolder.getContext(),并对返回的上下文对象调用 setAuthentication(anAuthentication),则 Authentication 对象将在共享同一 SecurityContext 实例的所有并发线程中发生更改。您可以自定义 SecurityContextPersistenceFilter 的行为,为每个请求创建一个全新的 SecurityContext,从而防止一个线程中的更改影响另一个线程。或者,您可以在临时更改上下文的位置创建一个新实例。SecurityContextHolder.createEmptyContext() 方法始终返回一个新的上下文实例。
归档时间: |
|
查看次数: |
4950 次 |
最近记录: |