【问题标题】:Can SecurityContextHolder Shared across usersSecurityContextHolder 能否跨用户共享
【发布时间】:2016-04-26 12:02:15
【问题描述】:

回答这个问题securitycontextholder-session-or-request-bound。 我正在使用此示例how-to-customAuthenticationManager 实现 CustomAuthenticationManager。事实证明,我的用户体验得到了 Accross Session。

例如,用户 A 与 Web App 交互,有时在访问配置文件时,用户 A 可以获取用户 B 的配置文件(这是因为应用程序正在从 SecurityContextHolder 的主体检索 UserProfileLoggedIn 并访问数据库),同时用户 B 已登录,但可能无法访问个人资料。

我想知道这是 SecurityContextHolder 泄漏吗?我知道 SecurityContextHolder 只是将 HttpSession 实现为包含 userDetails 等的容器的一种方式。

现在,在遇到问题后,我将 customAuthenticationManager 更改为 customAuthenticationProvider。有关更多信息,用户在中午大约有 100-500 个并发用户。

有关更多信息,我正在我的@Service 类中实现 SecurityContextHolder,以便其他团队成员可以轻松获得

@Service
public MyServiceImpl implement MyServiceInterface{
    public UserDetail findUser(){
       return (UserDetail) SecurityContextHolder.getContext().
              getAuthentication().getPrincipal();
     }
}

【问题讨论】:

  • 在挣扎了几个小时后,并实现了单例样式以从 Controller 获取 SecurityContextHolder 并传递给 Service,但我仍然遇到 SecurityContextHolder 泄漏问题。我仍然不知道可能是什么问题......

标签: java spring spring-security


【解决方案1】:

默认情况下,SecurityContextHolder 的实现绑定到ThreadLocal 的实例:

  • 它的可扩展性与您的容器为 Spring Security 提供同步线程一样多。
  • 抽象不是HttpSession的实现;但是,它提供与底层 HTTP Servlet 提供程序的集成,以将 HTTP 安全信息传输到 Spring 管理的应用层。
  • ThreadLocal 上的组合使 API 用户能够利用在不同线程中处理多个数据视图的优势。这也是为什么如果您在 HTTP 容器中有适当的线程配置,那么就用户数量而言,您不应该遇到可伸缩性问题。

【讨论】:

  • 您能分析一下我的情况可能是什么问题吗?是因为我没有在我的 customAuthenticationManger 中实现“ThreadLocal”,因为它覆盖了标准 ProviderManager 还是因为我正在设法从我的@Service 中获取 SecurityContextHolder。我的问题中的附加信息...
  • 您能否进一步更新您的问题,说明您如何在控制器中使用服务层?而且,您确定从 DAO 层获取正确的信息吗?
  • 如您所见,我已经更新了我的问题。我正在使用“@Service”将 SecurityContextHolder 包含在一个地方,以便其他组件可以使用它而无需初始化相同的代码。我想知道是因为这个实现吗?或者是因为我的实现如果 CustomAuthenticationManager ???如果是因为我的“@Service”实现,那么使用静态方法代替“@Service”是否安全?
  • 第一印象是您需要在 Controller 层使用 SecurityContextHolder 而不是 Service。原因很简单,你不能保证 Controller 和 Service 层都运行在同一个线程中。
  • 这就是我所说的......但是,如果我试图从 myService 和 myController 中获取用户详细信息,那么使用静态方法是否安全?因为如果我必须在每个 myControllers 中调用 getPrincipal ......真是太浪费了......
【解决方案2】:

我终于在我的代码中找到了根本问题。 我的一名团队成员正在@Service Class 中放置一个变量...... 像这样……

@Service 
public AnotherServiceImpl implements AnotherService{

  UserDetail userdetail;  //This is hillarious

  @Autowired
  MyServiceImpl myService;

  @Override
  public .......

   //......
}

显然我没有看到它的到来......在删除“UserDetail”变量后,一切都恢复原状...... 谢谢,我希望有人能从我的“愚蠢”错误中吸取教训

【讨论】:

    猜你喜欢
    • 2019-10-26
    • 2010-11-23
    • 1970-01-01
    • 2023-04-03
    • 2018-08-23
    • 2012-11-30
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多