如何自定义SecurityContextPersistenceFilter的行为? [英] How to customize the behaviour of SecurityContextPersistenceFilter?

查看:685
本文介绍了如何自定义SecurityContextPersistenceFilter的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I developing a stateless REST API that makes use of token based authentication, where I'm manually adding an Authentication object to the security context by calling SecurityContextHolder.getContext().setAuthentication(authentication) from within a custom security filter. I've been experiencing problems with the context not being set correctly which I believe is due to this :

在单个会话中接收并发请求的应用程序中,相同的SecurityContext实例将在线程之间共享.即使正在使用ThreadLocal,它也是从HttpSession中为每个线程检索的实例.如果您希望临时更改运行线程的上下文,则可能会产生影响.如果仅使用SecurityContextHolder.getContext(),并在返回的上下文对象上调用setAuthentication(anAuthentication),则在共享同一SecurityContext实例的所有并发线程中,Authentication对象都会更改. ...

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. ...

您可以自定义SecurityContextPersistenceFilter的行为,以便为每个请求创建一个全新的SecurityContext,从而防止一个线程中的更改影响另一个线程.

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的行为?

So the question is - how do you change the behaviour of the SecurityContextPersistenceFilter?

我希望安全上下文不与http会话相关联,但又不想将会话创建策略设置为无状态,因为我仍然想实现CSRF保护等.

I'd like the security context to not be associated with the http session, but don't want to set the session creation policy to stateless, because I still want to implement CSRF protection etc.

推荐答案

今天下午我有一个确切的问题,这个悬而未决的问题恰好与我的搜索相符,所以我想我会补充一点我学到的知识.

I had this exact question this afternoon, and this open question matched my search exactly, so I thought I would add the little I learned.

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

We had threads that were accessing the same SecurityContext. I was unable to figure out how to customize the behavior of the SecurityContextPersistenceFilter directly (and in the pattern of the framework), however there were two ways that I could get it to be thread safe.

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

The first solution was to ensure that an empty context was created in our main authentication filter. This covered all of our authenticated requests, so it would work for our solution.

SecurityContextHolder.createEmptyContext();

对我有用的第二件事是将WebSecurityConfig更改为无状态,我知道这不适用于OP,但为了完整性起见在此添加了

The second thing that worked for me was to change our WebSecurityConfig to be stateless, which I know doesn't work for the OP, but added here for completeness.

http.authorizeRequests()
  .anyRequest().authenticated()
  .and()
  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  ...

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

Both these solutions work independently for our particular configuration. I'm certain there is a 3rd solution that would read better, but I don't know what it is but would like to.

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

This is my first time posting. I welcome any feedback.

这篇关于如何自定义SecurityContextPersistenceFilter的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆