【问题标题】:Spring MVC, getting principal from security context in service layerSpring MVC,从服务层的安全上下文中获取主体
【发布时间】:2013-01-27 05:46:29
【问题描述】:
  1. 在 spring 控制器中获取主体作为参数 Principal principal 然后将其传递给服务层而不是通过 SecurityContextHolder.getContext().getAuthentication().getPrincipal() 立即在服务层中获取主体有什么优势?
  2. 在不检查 getAuthentication()getPrincipal() 对象的 null 处(类似于自定义包装器)的情况下,在服务层获取主要详细信息的最佳方法是什么?

【问题讨论】:

  • 您可能会发现this question 的答案很有用。 This answer 也很有用。
  • 使用静态方法的抽象类是否是一个很好的解决方案,我可以在其中放置SecurityContextHolder.getContext().getAuthentication().getPrincipal()?之后我可以在服务层使用它。
  • 再次阅读我给你的第二个链接。没有什么可以阻止您在服务中使用这种方法,如果您使用接口,也可以将其换出以进行测试。
  • 感谢您的解决方案。但是通过使用接口和实现,我需要将其注入到几乎每个服务中,或者可能注入到基础服务类中。使用静态方法怎么样(来自我上面的评论)?什么更好?

标签: java spring spring-mvc spring-security


【解决方案1】:
    • 您的服务 API 将更易于使用。您将直接看到对主体的依赖,因此您不会在主体不存在的环境中错误地调用某些服务方法。
    • 一般而言,对 SpringSecurity 代码的依赖较少意味着在迁移到新的 Spring Security 版本时问题较少。
    • 您将能够在没有 Spring Security 的环境中重用您的服务层。
  1. 准备一些包装类(例如AuthenticationService)。向其中添加 getPrincipal() 方法。实施您的检查。在直接调用 SecurityContextHolder 的地方注入 AuthenticationService。

【讨论】:

  • 如果我需要为特定用户获取一些数据,我认为在服务层获取主体(例如用户名)更安全,因为在此(限制)和数据库之间的层更少。因此,与在控制器中获取主体(之间的附加服务层)相比,它是唯一剩下的 dao。但另一方面,正如您所说,服务层可以更加可重用。你怎么看?
  • 一个主体对象被web层持有和保存。所以对我来说,从控制器到服务层的委托人看起来很自然。另一点是静态依赖对单元测试不利:misko.hevery.com/2008/12/15/…。我没有看到任何安全问题,因为 pincipal 实例是不可变的(通常此时密码将从实际实现中删除)。不好意思推迟了。我AFK很久了。
  • 在扩展的 BaseService(服务层)中使用选项 2 是否安全?
  • “安全”下是什么意思?
  • 它是线程安全的,因为主体是不可变的。但是,您可以有一个与多线程相关的小麻烦。想象一下,线程 A 像这样检查身份验证是否为空:SecurityContextHolder.getContext().getAuthentication() != null。然后线程 B 执行SecurityContextHolder.clearContext()。在这个线程 A 可能在这里有 NPE 之后:SecurityContextHolder.getContext().getAuthentication().getPrincipal()。为避免这种情况,请始终获取参考 Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
猜你喜欢
  • 2011-09-03
  • 2015-10-06
  • 2019-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多