Spring MVC,从服务层的安全上下文中获取主体

Ale*_*lex 15 java spring spring-mvc spring-security

  1. 将principal作为参数Principal principal在spring控制器中然后将其传递给服务层而不是立即获取服务层中的principal,有什么好处SecurityContextHolder.getContext().getAuthentication().getPrincipal()
  2. 获取服务层主体详细信息的最佳方法是什么,无需检查getAuthentication()getPrincipal()对象是否为空(如自定义包装器)?

Mak*_*das 12

    • 您的服务API将更易于使用.您将直接看到对主体的依赖,因此您不会在主体不存在的环境中错误地调用某些服务方法.
    • 通常,在迁移到新的Spring Security版本的情况下,对SpringSecurity代码的依赖性降低意味着更少的问题.
    • 您将能够在不存在Spring Security的环境中重用您的服务层.
  1. 准备一些包装类(例如AuthenticationService).添加getPrincipal()方法.实施你的支票.在任何地方注入AuthenticationService直接调用SecurityContextHolder.

  • 主体层由Web层保留和保留。因此,对于我来说,委托人从控制器到服务层看起来很自然。另一点是,静态依赖性不利于单元测试:http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/。我看不到任何安全性问题,因为主要实例是不可变的(通常,此时将从实际实现中删除密码)。不好意思推迟了。我是AFK很久了。 (2认同)
  • 它是线程安全的,因为主体是不可变的.但是,您可以有一个与多线程相关的问题.想象一下,线程A检查认证不是这样的:`SecurityContextHolder.getContext().getAuthentication()!= null`.然后线程B执行`SecurityContextHolder.clearContext()`.在此线程A之后可能有NPE:`SecurityContextHolder.getContext().getAuthentication().getPrincipal()`.为了避免这种情况,总是得到一个引用`Authentication authentication = SecurityContextHolder.getContext().getAuthentication()`. (2认同)