multithreading - 如何自定义SecurityContextPersistenceFilter的行为?

标签 multithreading spring-security spring-boot servlet-filters security-context

我正在开发一种无状态REST API,该API利用基于 token 的身份验证,其中我是通过从自定义安全过滤器中调用SecurityContextHolder.getContext().setAuthentication(authentication)手动将Authentication对象添加到安全上下文中的。我一直在遇到上下文设置不正确的问题,我认为这是由于以下原因:
Storing the SecurityContext between requests

In an application which receives concurrent requests in a single session, the same SecurityContext instance will be shared between threads. Even though a ThreadLocal is being used, it is the same instance that is retrieved from the HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use SecurityContextHolder.getContext(), and call setAuthentication(anAuthentication) on the returned context object, then the Authentication object will change in all concurrent threads which share the same SecurityContext instance. ...

You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another.


因此,问题是-如何更改SecurityContextPersistenceFilter的行为?
我希望安全上下文不与http session 相关联,但不想将 session 创建策略设置为无状态,因为我仍然想实现CSRF保护等。

最佳答案

今天下午我有一个确切的问题,这个悬而未决的问题与我的搜索完全吻合,所以我想我会补充一点我学到的知识。

我们有访问相同SecurityContext的线程。我无法弄清楚如何直接自定义SecurityContextPersistenceFilter的行为(以及按照框架的模式),但是我可以通过两种方法使它成为线程安全的。

第一个解决方案是确保在我们的主身份验证过滤器中创建一个空上下文。这涵盖了我们所有经过身份验证的请求,因此适用于我们的解决方案。

SecurityContextHolder.createEmptyContext();

对我有用的第二件事是将我们的WebSecurityConfig更改为无状态,我知道这不适用于OP,但为了完整性起见在此添加了它。
http.authorizeRequests()
  .anyRequest().authenticated()
  .and()
  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  ...

这两种解决方案都针对我们的特定配置独立工作。我敢肯定有第三个解决方案会更好看,但是我不知道这是什么,但我想这么做。

这是我第一次发帖。我欢迎任何反馈。

关于multithreading - 如何自定义SecurityContextPersistenceFilter的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30781498/

相关文章:

.net - ReaderWriterLockSlim : acquiring a read lock after an upgradeable lock doesn't throw LockRecursionException

grails - 创建名称为'statelessInvalidateTokenFilter的bean时出错

java - Spring 3 安全性 j_spring_security_check

spring-boot - 来自Spring Boot应用程序的Elastic Search远程连接

java - 如何让线程停止相互阻塞写入磁盘上的日志文件?

c++ - 使用条件变量进行双向通信时出现死锁

multithreading - libCurl 真的是线程安全的吗?

java - 如何使用 Spring Security 创建注销?

java - 什么时候在 java 中使用 Enum 类?

spring-boot - Thymeleaf th :if…th:errors do not display error message in page after @PostMapping method checks for @Valid