Java 如何将JAAS授权检查委托给Shiro?

Java 如何将JAAS授权检查委托给Shiro?,java,authorization,authentication,jaas,shiro,Java,Authorization,Authentication,Jaas,Shiro,我正在开发一个需要基于对象的身份验证和授权的服务器端应用程序。我喜欢Shiro的简单性,但为了与JAAS兼容,我编写了一个LoginModule,它使用ApacheShiro作为底层机制 但我的问题是,我找不到将JAAS授权检查委托给Shiro的方法。如何实现这一点?注意:答案涉及通过标准安全框架将外部授权系统与JVM集成的一般情况。它不是Shiro或JMX特定的,因为我对两者都不熟悉 从概念上讲,您似乎是在策略决策点(PDP)之后——也就是说,授权查询(“实体X允许做Y吗?”)是在这个工具上

我正在开发一个需要基于对象的身份验证和授权的服务器端应用程序。我喜欢Shiro的简单性,但为了与JAAS兼容,我编写了一个LoginModule,它使用ApacheShiro作为底层机制


但我的问题是,我找不到将JAAS授权检查委托给Shiro的方法。如何实现这一点?

注意:答案涉及通过标准安全框架将外部授权系统与JVM集成的一般情况。它不是Shiro或JMX特定的,因为我对两者都不熟悉


从概念上讲,您似乎是在策略决策点(PDP)之后——也就是说,授权查询(“实体X允许做Y吗?”)是在这个工具上进行评估的。JDK提供了以下几种:

  • 有效的方法,特别是它的
    checkXXX
    方法组
  • 类,尤其是它的
    意味着(权限)
    方法
  • 意味着(ProtectionDomain,Permission)
    有效的方法
  • 其次,
    意味着、、和的方法
  • 为了以递增粒度定制概念PDP的功能,可以覆盖上述任何方法。应该注意的是,JAAS并没有真正带来自己的PDP(与其名称相反);相反,除了源代码的原始信任因子外,它还为域和策略提供了支持基于主体的查询的支持。因此,在我看来,您对保持“JAAS兼容”的要求基本上转化为希望使用(原始加JAAS)JavaSE授权模型,即沙箱,我怀疑这不是您想要的。当标准模型被认为过于低级和/或性能密集时,往往会采用Shiro等框架;换句话说,当授权逻辑不需要为给定的一组信任因子计算每个堆栈帧时,因为这些因子通常是上下文不敏感的。根据我假设的有效性,有三种主要情况需要检查:

  • 授权是独立于访问控制上下文的。Shiro本机授权属性(SNAA),不管它们是什么,都适用于整个线程。代码来源是不相关的
  • 代码起源很重要,强制使用沙箱。SNAS仍然是独立于访问控制上下文的
  • 代码源和SNAS都是相关的,并且依赖于访问控制上下文

  • 1.仅基于SNAS的授权
  • 无论您认为合适与否,都可以管理身份验证。如果您希望继续使用JAAS'
    javax.security.auth
    SPI进行身份验证,请忘记将标准
    主题
    作为身份验证结果,而直接将特定于Shiro的主题绑定到线程本地存储。通过这种方式,您可以更方便地访问SNAAs,并避免使用
    AccessControlContext
    (并承受潜在风险)进行检索

  • 子类
    SecurityManager
    ,至少重写两个
    checkPermission
    方法,以便

  • 如有必要,将
    Permission
    参数翻译成Shiro的PDP(SPDP)理解的内容,然后
  • 使用线程本地SNAAs和权限委托给SPDP(并在SPDP发出拒绝访问信号时抛出
    SecurityException
  • 接收重载的安全上下文可能会忽略相应的参数。在应用程序初始化时,实例化并安装(
    System::setSecurityManager
    )您的实现


    2.混合授权,将源代码与上下文不敏感的SNAAs相结合
  • 以您认为合适的方式管理身份验证;再次将Shiro特有的
    主题
    与线程本身关联起来
  • 子类
    SecurityManager
    ,至少覆盖两个
    checkPermission
    方法,这一次,使它们同时委托给SPDP和/或被覆盖的实现(后者相应地调用当前或提供的访问控制上下文上的
    checkPermission
    )。对于任何给定的许可,应咨询哪一个(或多个)以及以何种顺序进行咨询,这当然取决于实施情况。当两者都被调用时,应该首先查询SPDP,因为它的响应速度可能比访问控制上下文更快
  • 如果SPDP要另外处理对源自某个位置和/或一组代码签名者的代码授予的权限的评估,您还必须将
    策略
    子类化,实现
    暗示(ProtectionDomain,Permission)
    ,这样,与上面的
    SecurityManager::checkPermission
    类似,它向SPDP传递一些可理解的域表示(通常只传递其
    CodeSource
    )和权限参数(但逻辑上不传递SNAAs)。该实现应尽可能高效,因为它将在
    checkPermission
    时间为每个访问控制上下文的每个域调用一次。实例化并安装(
    Policy::setPolicy
    )您的实现

  • 3.混合授权,将源代码与SNAAs相结合,两者都是上下文敏感的
  • 无论您认为合适与否,都可以管理身份验证。不幸的是,在本例中,主题处理部分并不像创建
    ThreadLocal
    那样简单

  • 子类化、实例化并安装一个
    策略
    ,该策略执行
    安全管理器::检查权限
    策略::暗示
    的组合职责,如第二种情况中所述

  • 实例化并安装标准的
    SecurityManager

  • 创建
    ProtectionDomain
    子类capab