此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Security 7.0.4spring-doc.cadn.net.cn

Java 认证和授权服务(JAAS)提供者

Spring Security 提供了一个包,用于将身份验证请求委托给 Java 身份验证和授权服务(JAAS)。 本节将讨论该包。spring-doc.cadn.net.cn

抽象 JAAS 认证提供者

AbstractJaasAuthenticationProvider 类是所提供的 JAAS AuthenticationProvider 实现的基础。 子类必须实现一个用于创建 LoginContext 的方法。 AbstractJaasAuthenticationProvider 具有多个依赖项,这些依赖项可被注入其中,如下文本节其余部分所述。spring-doc.cadn.net.cn

JAAS 回调处理器

大多数 JAAS LoginModule 实例都需要某种形式的回调。 这些回调通常用于从用户处获取用户名和密码。spring-doc.cadn.net.cn

在 Spring Security 的部署中,Spring Security 负责处理该用户交互(通过认证机制)。 因此,当认证请求被委托给 JAAS 时,Spring Security 的认证机制已经完全填充了一个包含 JAAS Authentication 所需全部信息的 LoginModule 对象。spring-doc.cadn.net.cn

因此,Spring Security 的 JAAS 包提供了两个默认的回调处理器:JaasNameCallbackHandlerJaasPasswordCallbackHandler。 这些回调处理器均实现了 JaasAuthenticationCallbackHandler 接口。 在大多数情况下,无需了解其内部机制即可直接使用这些回调处理器。spring-doc.cadn.net.cn

对于那些需要完全控制回调行为的人,AbstractJaasAuthenticationProvider 在内部将这些 JaasAuthenticationCallbackHandler 实例包装在一个 InternalCallbackHandler 中。 InternalCallbackHandler 是实际实现 JAAS 标准 CallbackHandler 接口的类。 每当使用 JAAS LoginModule 时,都会传入一个配置了 InternalCallbackHandler 实例的应用程序上下文列表。 如果 LoginModule 请求对 InternalCallbackHandler 实例进行回调,则该回调会依次传递给被包装的 JaasAuthenticationCallbackHandler 实例。spring-doc.cadn.net.cn

JAAS 权限授予器

JAAS 使用主体(Principal)进行工作。 在 JAAS 中,即使是“角色”也以主体的形式表示。 而 Spring Security 则使用 Authentication 对象。 每个 Authentication 对象包含一个单一的主体(principal)和多个 GrantedAuthority 实例。 为了便于在这些不同概念之间进行映射,Spring Security 的 JAAS 包中包含了一个 AuthorityGranter 接口。spring-doc.cadn.net.cn

一个 AuthorityGranter 负责检查 JAAS 主体,并返回一组代表分配给该主体的权限的 String 对象。 对于每个返回的权限字符串,AbstractJaasAuthenticationProvider 会创建一个 JaasGrantedAuthority(它实现了 Spring Security 的 GrantedAuthority 接口),其中包含权限字符串以及传递给 AuthorityGranter 的 JAAS 主体。 AbstractJaasAuthenticationProvider 通过首先使用 JAAS LoginModule 成功验证用户凭据,然后访问其返回的 LoginContext 来获取 JAAS 主体。 会调用 LoginContext.getSubject().getPrincipals(),并将每个生成的主体传递给针对 AbstractJaasAuthenticationProvider.setAuthorityGranters(List) 属性定义的每个 AuthorityGranterspring-doc.cadn.net.cn

Spring Security 不包含任何生产用的 AuthorityGranter 实例,因为每个 JAAS 主体的具体含义是实现特定的。 但是,在单元测试中有一个 TestAuthorityGranter ,它展示了简单的 AuthorityGranter 实现。spring-doc.cadn.net.cn

DefaultJaasAuthenticationProvider

DefaultJaasAuthenticationProvider 允许将一个 JAAS Configuration 对象作为依赖注入其中。 然后,它使用注入的 JAAS LoginContext 创建一个 Configuration。 这意味着 DefaultJaasAuthenticationProvider 不像 Configuration 那样绑定到任何特定的 JaasAuthenticationProvider 实现。spring-doc.cadn.net.cn

内存配置

为了便于将 Configuration 注入到 DefaultJaasAuthenticationProvider,系统提供了一个名为 InMemoryConfiguration 的默认内存实现。 该实现的构造函数接受一个 Map,其中每个键代表登录配置名称,而值则代表一组 AppConfigurationEntry 实例的 ArrayInMemoryConfiguration 还支持一个默认的 AppConfigurationEntry 对象 Array,如果在提供的 Map 中未找到映射,则将使用此默认值。 有关详细信息,请参阅 InMemoryConfiguration 的 Javadoc。spring-doc.cadn.net.cn

DefaultJaasAuthenticationProvider 示例配置

虽然 InMemoryConfiguration 的 Spring 配置可能比标准的 JAAS 配置文件更为冗长,但将其与 DefaultJaasAuthenticationProvider 结合使用时,相比 JaasAuthenticationProvider 更加灵活,因为它不依赖于默认的 Configuration 实现。spring-doc.cadn.net.cn

下一个示例展示了使用 DefaultJaasAuthenticationProviderInMemoryConfiguration 配置。 请注意,自定义的 Configuration 实现也可以轻松注入到 DefaultJaasAuthenticationProvider 中。spring-doc.cadn.net.cn

<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>

JAAS 认证提供者

JaasAuthenticationProvider 假设默认的 ConfigurationConfigFile 的一个实例。 做出此假设是为了尝试更新 Configuration。 随后,JaasAuthenticationProvider 使用默认的 Configuration 来创建 LoginContextspring-doc.cadn.net.cn

假设我们有一个 JAAS 登录配置文件 /WEB-INF/login.conf,其内容如下:spring-doc.cadn.net.cn

JAASTest {
	sample.SampleLoginModule required;
};

与所有 Spring Security 的 Bean 一样,JaasAuthenticationProvider 通过应用上下文进行配置。 以下定义对应于上述 JAAS 登录配置文件:spring-doc.cadn.net.cn

<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 会尝试以 Subject 上的 JaasAuthenticationToken 身份运行。 这意味着可以使用以下方式访问 Subjectspring-doc.cadn.net.cn

Subject subject = Subject.getSubject(AccessController.getContext());

您可以通过使用 jaas-api-provision 属性来配置此集成。 当与依赖于 JAAS Subject 被填充的旧系统或外部 API 进行集成时,此功能非常有用。spring-doc.cadn.net.cn