On this page
31. Java 身份验证和授权服务(JAAS)提供程序
31.1 Overview
Spring Security 提供了一个程序包,可以将身份验证请求委派给 Java 身份验证和授权服务(JAAS)。该软件包将在下面详细讨论。
31.2 AbstractJaasAuthenticationProvider
AbstractJaasAuthenticationProvider是所提供的 JAAS AuthenticationProvider实现的基础。子类必须实现创建LoginContext的方法。 AbstractJaasAuthenticationProvider具有许多可以注入到其中的依赖项,下面将对此进行讨论。
31.2.1 JAAS CallbackHandler
大多数 JAAS LoginModule都需要某种回调。这些回调通常用于从用户获取用户名和密码。
在 Spring Security 部署中,Spring Security 负责此用户交互(通过身份验证机制)。因此,在将身份验证请求委托给 JAAS 时,Spring Security 的身份验证机制将已经完全填充了Authentication对象,其中包含 JAAS LoginModule所需的所有信息。
因此,Spring Security 的 JAAS 包提供了两个默认的回调处理程序JaasNameCallbackHandler和JaasPasswordCallbackHandler。这些回调处理程序中的每一个都实现JaasAuthenticationCallbackHandler。在大多数情况下,无需了解内部机制即可简单地使用这些回调处理程序。
对于需要完全控制回调行为的用户,内部AbstractJaasAuthenticationProvider将这些JaasAuthenticationCallbackHandler换成InternalCallbackHandler。 InternalCallbackHandler是实际实现 JAAS 常规CallbackHandler接口的类。每当使用 JAAS LoginModule时,都会向其传递配置了InternalCallbackHandler的应用程序上下文列表。如果LoginModule请求针对InternalCallbackHandler的回调,则该回调又传递给正在包装的JaasAuthenticationCallbackHandler。
31.2.2 JAAS AuthorityGranter
JAAS 与校长合作。 JAAS 中甚至将“角色”表示为主体。另一方面,Spring Security 可以处理Authentication个对象。每个Authentication对象包含一个主体和多个GrantedAuthority。为了促进这些不同概念之间的 Map,Spring Security 的 JAAS 软件包包括一个AuthorityGranter接口。
AuthorityGranter负责检查 JAAS 委托人并返回一组String,代表分配给委托人的权限。对于每个返回的授权字符串,AbstractJaasAuthenticationProvider创建一个JaasGrantedAuthority(它实现 Spring Security 的GrantedAuthority接口),其中包含授权字符串和AuthorityGranter传递的 JAAS 主体。 AbstractJaasAuthenticationProvider首先通过使用 JAAS LoginModule成功验证用户的凭据,然后访问它返回的LoginContext,从而获得 JAAS 主体。调用LoginContext.getSubject().getPrincipals(),并将每个结果主体传递给针对AbstractJaasAuthenticationProvider.setAuthorityGranters(List)属性定义的每个AuthorityGranter。
鉴于每个 JAAS 主体都具有特定于实现的含义,因此 Spring Security 不包含任何生产AuthorityGranter。但是,单元测试中有一个TestAuthorityGranter演示了一个简单的AuthorityGranter实现。
31.3 DefaultJaasAuthenticationProvider
DefaultJaasAuthenticationProvider允许将 JAAS Configuration对象作为依赖项注入到该对象中。然后,使用注入的 JAAS Configuration创建一个LoginContext。这意味着DefaultJaasAuthenticationProvider和JaasAuthenticationProvider一样不受Configuration的任何特定实现的约束。
31.3.1 InMemoryConfiguration
为了便于将Configuration注入DefaultJaasAuthenticationProvider,提供了默认的内存实现InMemoryConfiguration。实现构造函数接受一个Map,其中每个键代表一个登录配置名称,该值代表一个AppConfigurationEntry的Array。 InMemoryConfiguration还支持AppConfigurationEntry对象的默认Array,如果在提供的Map中找不到 Map,则将使用它们。有关详细信息,请参考InMemoryConfiguration的类级别 javadoc。
31.3.2 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>
31.4 JaasAuthenticationProvider
JaasAuthenticationProvider假定默认的Configuration是ConfigFile的实例。进行此假设是为了尝试更新Configuration。 JaasAuthenticationProvider然后使用默认的Configuration创建LoginContext。
假设我们有一个 JAAS 登录配置文件/WEB-INF/login.conf,其内容如下:
JAASTest {
sample.SampleLoginModule required;
};
像所有 Spring Security 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>
31.5 以主题身份运行
如果已配置,则JaasApiIntegrationFilter将尝试在JaasAuthenticationToken上以Subject的身份运行。这意味着可以使用以下命令访问Subject:
Subject subject = Subject.getSubject(AccessController.getContext());
可以使用jaas-api-provision属性轻松配置此集成。与依赖于填充 JAAS 主题的旧版或外部 API 集成时,此功能很有用。