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

本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

Spring Security 提供了一个包,用于将认证请求委托给Java认证和授权服务(Java Authentication and Authorization Service)(JAAS)。本节将讨论该包。

AbstractJaasAuthenticationProvider

AbstractJaasAuthenticationProvider 类是所提供的 JAAS AuthenticationProvider 实现的基础。子类必须实现一个创建 LoginContext 的方法。AbstractJaasAuthenticationProvider 有一些可以注入它的依赖关系,这在本节的其余部分中讨论。

JAAS回调程序(CallbackHandler)

大多数 JAAS LoginModule 实例都需要某种回调。这些回调通常用于从用户那里获得用户名和密码。

在Spring Security部署中,Spring Security负责这种用户互动(通过认证机制)。因此,当认证请求被委托给JAAS时,Spring Security 的认证机制已经完全填充了一个 Authentication 对象,其中包含了JAAS LoginModule 所需的所有信息。

因此,Spring Security 的 JAAS 包提供了两个默认的回调处理程序。JaasNameCallbackHandlerJaasPasswordCallbackHandler。这些回调处理程序都实现了 JaasAuthenticationCallbackHandler。在大多数情况下,这些回调处理程序可以在不了解内部机制的情况下使用。

对于那些需要完全控制回调行为的人来说,AbstractJaasAuthenticationProvider 在内部用一个 InternalCallbackHandler 包装这些 JaasAuthenticationCallbackHandler 实例。 InternalCallbackHandler 是实际实现 JAAS 正常 CallbackHandler 接口的类。在使用JAAS LoginModule 的任何时候,它都会被传递给一个配置了 InternalCallbackHandler 实例的 application context 列表。如果 LoginModule 请求对 InternalCallbackHandler 实例进行回调,则回调会被传递给被包装的 JaasAuthenticationCallbackHandler 实例。

JAAS AuthorityGranter

JAAS的工作是以 principal 为中心的。甚至 “roles” 在JAAS中也被表示为委托人(principal)。另一方面,Spring Security 使用的是 Authentication 对象。每个 Authentication 对象包含一个委托人和多个 GrantedAuthority 实例。为了促进这些不同概念之间的映射,Spring Security 的 JAAS包包括一个 AuthorityGranter 接口。

AuthorityGranter 负责检查JAAS委托人并返回一组代表分配给principal(委托人)的授权的String对象。对于每个返回的授权字符串,AbstractJaasAuthenticationProvider 会创建一个 JaasGrantedAuthority(实现Spring Security的 GrantedAuthority 接口),其中包含授权字符串和 AuthorityGranter 所传递的JAAS principal。AbstractJaasAuthenticationProvider 通过使用JAAS LoginModule 首先成功地验证了用户的凭证,然后访问它返回的 LoginContext 来获得JAAS principal。对 LoginContext.getSubject().getPrincipals() 进行调用,将得到的每个委托人传递给针对 AbstractJaasAuthenticationProvider.setAuthorityGranters(List) 属性定义的每个 AuthorityGranter

Spring Security 不包括任何生产型的 AuthorityGranter 实例,因为每个JAAS principal(委托人)都有特定的实现含义。然而,单元测试中有一个 TestAuthorityGranter,演示了一个简单的 AuthorityGranter 实现。

DefaultJaasAuthenticationProvider

DefaultJaasAuthenticationProvider 允许将一个JAAS Configuration 对象作为依赖关系注入它。然后它通过使用注入的JAAS Configuration 创建一个 LoginContext。这意味着 DefaultJaasAuthenticationProvider 并不像 JaasAuthenticationProvider 那样被绑定到任何特定的 Configuration 实现。

InMemoryConfiguration

为了方便将 Configuration 注入 DefaultJaasAuthenticationProvider,我们提供了一个默认的内存实现,名为 InMemoryConfiguration。该实现的构造函数接受一个 Map,其中每个key代表一个登录 configuration 名称,而值代表一个 AppConfigurationEntry 实例的数组。InMemoryConfiguration 还支持一个默认的 AppConfigurationEntry 对象数组,如果在提供的 Map 中没有找到映射,则使用该数组。有关详细信息,请参见 InMemoryConfiguration 的 Javadoc

DefaultJaasAuthenticationProvider Configuration 示例

虽然 InMemoryConfiguration 的 Spring configuration 可能比标准的JAAS配置文件更加冗长,但与 DefaultJaasAuthenticationProvider 一起使用它比 JaasAuthenticationProvider 更加灵活,因为它不依赖于默认的 Configuration 实现。

下一个例子提供了一个使用 InMemoryConfigurationDefaultJaasAuthenticationProvider 的配置。请注意,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 假定默认 ConfigurationConfigFile 的一个实例。做出这个假设是为了尝试更新该 ConfigurationJaasAuthenticationProvider 然后使用默认 Configuration 来创建 LoginContext

假设我们有一个JAAS 登录 configuration 文件,/WEB-INF/login.conf,其内容如下。

JAASTest {
	sample.SampleLoginModule required;
};

像所有的Spring Security Bean一样,JaasAuthenticationProvider 是通过 application context 配置的。下面的定义将对应于上述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>

以 Subject 运行

如果配置了,JaasApiIntegrationFilter 会尝试作为 JaasAuthenticationTokenSubject 运行。这意味着可以用以下方式访问 Subject

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

您可以通过使用 jaas-api-provision 属性来配置这种集成。在与依赖JAAS Subject 填充的传统或外部API集成时,这一功能非常有用。