java如何将JAAS授权检查委托给Shiro?
我正在开发一个需要基于对象的身份验证和授权的服务器端应用程序。我喜欢Shiro的简单性,但为了与JAAS兼容,我编写了一个LoginModule,它使用ApacheShiro作为底层机制
但我的问题是,我找不到将JAAS授权检查委托给Shiro的方法。我怎样才能做到这一点
你可以在下面搜索框中键入要查询的问题!
我正在开发一个需要基于对象的身份验证和授权的服务器端应用程序。我喜欢Shiro的简单性,但为了与JAAS兼容,我编写了一个LoginModule,它使用ApacheShiro作为底层机制
但我的问题是,我找不到将JAAS授权检查委托给Shiro的方法。我怎样才能做到这一点
# 1 楼答案
注:答案涉及通过标准安全框架将外部授权系统与JVM集成的一般情况。这不是Shiro或JMX特有的,因为我对它们都不熟悉
从概念上讲,您似乎是在策略决策点(PDP)之后,即授权查询(“实体X允许做Y吗?”)进行评估,也就是说。JDK提供了以下几种:
checkXXX
组方法李>implies(Permission)
方法李>implies(ProtectionDomain, Permission)
方法李>为了以递增粒度定制概念PDP的功能,可以覆盖上述任何方法。应该指出的是,JAAS并没有真正带来自己的PDP(与其名称相反);相反,它为域和策略提供了means,以支持基于主体的查询,此外还提供了源代码的原始信任因子。因此,在我看来,您保持“JAAS兼容”的要求基本上转化为希望使用(原始加JAAS)JavaSE授权模型,即沙箱,我怀疑这不是您想要的。当标准模型被认为过于低级和/或性能密集时,往往会使用Shiro等框架;换句话说,当授权逻辑不需要为给定的一组信任因子评估每个堆栈帧时,因为这些因子通常对上下文不敏感。根据我假设的有效性,有三种主要情况需要检查:
AccessControlContext
独立的。Shiro native authorization attributes(SNAA),不管它们是什么,都适用于整个线程。代码来源无关紧要李>AccessControlContext
独立的李>AccessControlContext
-依赖于李>一,。仅基于SNAAs的授权
无论你认为合适与否,都要管理身份验证。如果希望继续使用JAAS
javax.security.auth
SPI进行身份验证,请忘记建立一个标准Subject
作为身份验证结果,而是直接将特定于Shiro的一个绑定到线程本地存储。通过这种方式,您可以更方便地访问SNAAs,并避免使用AccessControlContext
(并遭受潜在的performance penalty)进行检索子类
SecurityManager
,重写至少两个checkPermission
方法,以便Permission
参数翻译成Shiro的PDP(SPDP)在SecurityException
)李>接收重载的安全上下文可能会忽略相应的参数。在应用程序初始化时,实例化并安装(
System::setSecurityManager
)您的实现二,。混合授权,将源代码与不区分上下文的SNAAs结合起来
Subject
与线程本身关联起来李>SecurityManager
,至少重写两个checkPermission
方法,这一次,它们将委托给SPDP和/或重写的实现(后者反过来相应地调用当前或提供的访问控制上下文上的checkPermission
)。对于任何给定的许可,应咨询哪一个(或多个)以及以何种顺序进行咨询,这当然取决于实施情况。当两者都被调用时,应该首先查询SPDP,因为它的响应速度可能比访问控制上下文更快李>Policy
子类化,实现implies(ProtectionDomain, Permission)
,这样,就像上面的SecurityManager::checkPermission
,它将一些可理解的域表示(通常仅其CodeSource
)和权限参数传递给SPDP,但从逻辑上讲,而不是SNAA。该实现应该尽可能高效,因为它将在checkPermission
时间为每个访问控制上下文的每个域调用一次。实例化并安装(Policy::setPolicy
)您的实现李>三,。混合授权,将源代码与SNAAs相结合,两者都与上下文相关
无论你认为合适与否,都要管理身份验证。不幸的是,在本例中,主题处理部分并不像创建
ThreadLocal
那么简单子类化、实例化并安装一个
Policy
,它执行SecurityManager::checkPermission
和Policy::implies
的组合职责,如第二种情况中单独描述的那样实例化并安装一个标准
SecurityManager
创建一个
ProtectionDomain
子类,能够存储和公开SNAAs作者1a^{}
是用SNAS构建的
实现
combine(ProtectionDomain[], ProtectionDomain[])
,以便与}方法时都会调用它
Policy::implies
一样,实现应该是高效的(例如通过消除重复),因为每次调用getContext
和checkPermission
{身份验证成功后,创建一个新的
AccessControlContext
来包装当前的DomainCombiner
,以及一个自定义的DomainCombiner
实例,反过来包装SNAAs。将要执行的代码包装到 这一点“在”一个AccessController::doPrivilegedWithCombiner
调用中,也传递替换访问控制上下文1除了使用自定义域和您自己的组合器实现之外,还有一种看似更简单的替代方法,将SNAA转换为
Principal
,并使用标准SubjectDomainCombiner
,将它们绑定到当前AccessControlContext
的域(如上所述,或者简单地通过Subject::doAs
)。这种方法是否会降低策略的效率主要取决于调用堆栈的深度(访问控制上下文包含多少不同的域)。最终,在编写策略时,您认为可以避免作为域合并器的一部分实现的缓存优化将对您产生影响,因此这本质上是您必须在那时做出的设计决策