在threadlocal中保持“当前用户”
Posted
技术标签:
【中文标题】在threadlocal中保持“当前用户”【英文标题】:Keeping "current user" in threadlocal 【发布时间】:2013-08-16 01:37:34 【问题描述】:我有一个 spring-mvc 应用程序,它当前有两个通道 - Web 应用程序和一个 REST 服务。两者都有用户的 http 会话,我可以轻松地在我的服务类中获取“当前用户”。
现在我需要开发另一个没有 http 会话并且当前用户依赖于请求参数的 REST 服务。因此控制器会读取该请求参数并找到当前用户。
现在我要么需要: 1.修改我的服务层方法以接受当前用户作为参数 要么 2.只需修改从http会话中获取当前用户的类即可。
我还需要创建一个审计日志,我将为此使用 Spring AOP。 Aspect 也需要访问“当前用户”。所以选项 #1 可能对我不起作用,我会选择 #2。
对于选项 #2,我将创建一个拦截器,将当前用户放入 ThreadLocal 变量中。新 REST 服务的控制器将执行相同的操作,然后在我的服务层和审计日志方面,我可以从那里获取当前用户。
我以前没有做过类似的事情,想知道是否有更好的方法。或者我应该期待这种方法会出现什么样的问题。
我会感谢任何 cmets 和想法。
盎司
这是我目前获取当前用户的方式:
@Override
public User getCurrentUser()
Authentication currentUser = getAuthentication();
return userService.getByLoginName(currentUser.getName());
protected Authentication getAuthentication()
return SecurityContextHolder.getContext().getAuthentication();
【问题讨论】:
一些代码可能会有所帮助。我了解到您正在从服务层访问 http 会话,对吗? 是的,我用示例更新了我的帖子。 ***.com/questions/14823761/… 很抱歉,但这并不能回答我的问题。我已经有一项服务可以从 http 会话中获取当前用户,并且我没有在任何其他地方直接调用 http 会话或 spring 上下文。问题是我不能再使用这种方法了,因为有了新的 REST 服务。 您应该将用户作为参数从您的控制器传递给您的服务方法。我看不出有什么问题 【参考方案1】:我认为满足您需要的一种简单方法是为您的新 REST Web 服务配置一个 servlet 过滤器,以使用来自请求参数的 Authentication
对象构建填充 SecurityContextHolder
。
您可以阅读:http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e2171 了解更多详情。
使用此解决方案,您无需修改代码即可检索当前用户。 (注意SecurityContextHolder
已经在使用ThreadLocal
来存储SecurityContext
和Authentication
)
【讨论】:
谢谢!这实际上是最简单的方法。我可以直接在我的 REST 控制器中设置身份验证对象,而不是使用过滤器,因为请求是 XML 格式并且需要额外的转换。以上是关于在threadlocal中保持“当前用户”的主要内容,如果未能解决你的问题,请参考以下文章