# Java 身份验证和授权服务提供者
# 概述
Spring 安全性提供了一种包,能够将身份验证请求委托给 Java 身份验证和授权服务。下面将详细讨论这个包。
# 抽象 JaasAuthenticationProvider
AbstractJaasAuthenticationProvider
是所提供的 JAASAuthenticationProvider
实现的基础。子类必须实现创建LoginContext
的方法。AbstractJaasAuthenticationProvider
具有许多可以注入其中的依赖项,这些依赖项将在下面讨论。
# JAAS CallbackHandler
大多数 JAASLoginModule
s 都需要某种类型的回调。这些回调通常用于从用户获得用户名和密码。
在 Spring 安全性部署中, Spring 安全性负责此用户交互(通过身份验证机制)。因此,在将身份验证请求委托给 JAAS 时, Spring Security 的身份验证机制将已经完全填充了一个Authentication
对象,该对象包含 JAASLoginModule
所需的所有信息。
因此, Spring Security 的 JAAS 包提供了两个默认的回调处理程序,JaasNameCallbackHandler
和JaasPasswordCallbackHandler
。这些回调处理程序中的每一个都实现JaasAuthenticationCallbackHandler
。在大多数情况下,这些回调处理程序可以在不了解内部机制的情况下简单地使用。
对于那些需要完全控制回调行为的人,内部AbstractJaasAuthenticationProvider
将这些JaasAuthenticationCallbackHandler
s 包装成InternalCallbackHandler
。InternalCallbackHandler
是实际实现 JAASNormalCallbackHandler
接口的类。每当使用 JAASLoginModule
时,都会传递一个配置InternalCallbackHandler
s 的应用程序上下文列表。如果LoginModule
对InternalCallbackHandler
s 请求回调,则回调依次传递给正在打包的JaasAuthenticationCallbackHandler
s。
# Jaas AuthorityGranter
JAAS 与校长一起工作。在 JAAS 中,甚至连“角色”也被表示为主体。 Spring 另一方面,安全性适用于Authentication
对象。每个Authentication
对象包含一个主体,以及多个GrantedAuthority
s。为了便于在这些不同概念之间进行映射, Spring Security 的 JAAS 包包括一个AuthorityGranter
接口。
一个AuthorityGranter
负责检查一个 JAAS 主体,并返回一组String
s,代表分配给主体的权限。对于每个返回的权限字符串,AbstractJaasAuthenticationProvider
创建一个JaasGrantedAuthority
(它实现 Spring Security 的GrantedAuthority
接口),其中包含权限字符串和传递AuthorityGranter
的 JAAS 主体。AbstractJaasAuthenticationProvider
首先通过使用 JAASLoginModule
成功验证用户的凭据来获得 JAAS 主体,然后访问它返回的LoginContext
。对LoginContext.getSubject().getPrincipals()
进行了调用,将每个生成的主体传递给根据AbstractJaasAuthenticationProvider.setAuthorityGranters(List)
属性定义的每个AuthorityGranter
。
Spring 考虑到每个 JAAS 主体都具有特定于实现的含义,安全性不包括任何AuthorityGranter
s 的产品。然而,在单元测试中有一个TestAuthorityGranter
演示了一个简单的AuthorityGranter
实现。
# DefaultJaasAuthenticationProvider
DefaultJaasAuthenticationProvider
允许将 JAASConfiguration
对象作为依赖项注入其中。然后,它使用注入的 JAAS创建。这意味着DefaultJaasAuthenticationProvider
不绑定Configuration
作为JaasAuthenticationProvider
的任何特定实现。
# 记忆组态
为了方便地将Configuration
注入DefaultJaasAuthenticationProvider
,提供了一个名为InMemoryConfiguration
的默认内存中实现。实现构造函数接受一个Map
,其中每个键表示一个登录配置名,该值表示Array
的AppConfigurationEntry
s。InMemoryConfiguration
还支持一个Array
的缺省Array
的AppConfigurationEntry
对象,如果在提供的Map
中找不到映射,则将使用该对象。有关详细信息,请参阅InMemoryConfiguration
的类级别 Javadoc。
# DefaultJaasAuthenticationProvider 示例配置
虽然InMemoryConfiguration
的 Spring 配置可以比标准的 JAAS 配置文件更详细,但与DefaultJaasAuthenticationProvider
一起使用它比JaasAuthenticationProvider
更灵活,因为它不依赖于默认的Configuration
实现。
下面提供了使用InMemoryConfiguration
的DefaultJaasAuthenticationProvider
的配置示例。请注意,Configuration
的自定义实现也可以很容易地注入到DefaultJaasAuthenticationProvider
中。
<bean id="jaasAuthProvider"
class="org.springframework.security.authentication.jaas.DefaultJaasAuthenticationProvider">
<property name="configuration">
<bean class="org.springframework.security.authentication.jaas.memory.InMemoryConfiguration">
<constructor-arg>
<map>
<!--
SPRINGSECURITY is the default loginContextName
for AbstractJaasAuthenticationProvider
-->
<entry key="SPRINGSECURITY">
<array>
<bean class="javax.security.auth.login.AppConfigurationEntry">
<constructor-arg value="sample.SampleLoginModule" />
<constructor-arg>
<util:constant static-field=
"javax.security.auth.login.AppConfigurationEntry$LoginModuleControlFlag.REQUIRED"/>
</constructor-arg>
<constructor-arg>
<map></map>
</constructor-arg>
</bean>
</array>
</entry>
</map>
</constructor-arg>
</bean>
</property>
<property name="authorityGranters">
<list>
<!-- You will need to write your own implementation of AuthorityGranter -->
<bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
</list>
</property>
</bean>
# JaasAuthenticationProvider
JaasAuthenticationProvider
假设默认的Configuration
是配置文件 (opens new window)的实例。这个假设是为了尝试更新Configuration
。然后JaasAuthenticationProvider
使用默认的Configuration
来创建LoginContext
。
假设我们有一个 JAAS 登录配置文件/WEB-INF/login.conf
,其内容如下:
JAASTest {
sample.SampleLoginModule required;
};
与所有 Spring 安全 bean 一样,JaasAuthenticationProvider
也是通过应用程序上下文配置的。以下定义对应于上面的 JAAS 登录配置文件:
<bean id="jaasAuthenticationProvider"
class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
<property name="loginConfig" value="/WEB-INF/login.conf"/>
<property name="loginContextName" value="JAASTest"/>
<property name="callbackHandlers">
<list>
<bean
class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
<bean
class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler"/>
</list>
</property>
<property name="authorityGranters">
<list>
<bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
</list>
</property>
</bean>
# 以跑步为主题
如果进行了配置,JaasApiIntegrationFilter
将尝试在JaasAuthenticationToken
上以Subject
的形式运行。这意味着Subject
可以通过以下方式访问:
Subject subject = Subject.getSubject(AccessController.getContext());
可以使用JAAS-API-供应属性轻松配置此集成。当与依赖于填充的 JAAS 主题的遗留或外部 API 集成时,此功能非常有用。