Java 身份驗證和授權服務 (JAAS) 提供者

Spring Security 提供了一個包,用於將身份驗證請求委託給 Java 身份驗證和授權服務 (JAAS)。本節討論該包。

AbstractJaasAuthenticationProvider

AbstractJaasAuthenticationProvider 類是提供的 JAAS AuthenticationProvider 實現的基礎。子類必須實現一個建立 LoginContext 的方法。AbstractJaasAuthenticationProvider 有許多可以注入的依賴項,如本節其餘部分所述。

JAAS CallbackHandler

大多數 JAAS LoginModule 例項需要某種形式的回撥。這些回撥通常用於從使用者那裡獲取使用者名稱和密碼。

在 Spring Security 部署中,Spring Security 負責這種使用者互動(透過身份驗證機制)。因此,當身份驗證請求被委託給 JAAS 時,Spring Security 的身份驗證機制已經完全填充了一個包含 JAAS LoginModule 所需所有資訊的 Authentication 物件。

因此,Spring Security 的 JAAS 包提供了兩個預設的回撥處理器:JaasNameCallbackHandlerJaasPasswordCallbackHandler。每個回撥處理器都實現了 JaasAuthenticationCallbackHandler。在大多數情況下,無需瞭解內部機制即可使用這些回撥處理器。

對於需要完全控制回撥行為的使用者,AbstractJaasAuthenticationProvider 在內部使用 InternalCallbackHandler 包裝這些 JaasAuthenticationCallbackHandler 例項。InternalCallbackHandler 是實際實現 JAAS 標準 CallbackHandler 介面的類。任何時候使用 JAAS LoginModule 時,都會向其傳遞一個應用程式上下文配置的 InternalCallbackHandler 例項列表。如果 LoginModuleInternalCallbackHandler 例項請求回撥,則回撥又會傳遞給被包裝的 JaasAuthenticationCallbackHandler 例項。

JAAS AuthorityGranter

JAAS 使用主體(principals)。即使“角色”在 JAAS 中也表示為主體。另一方面,Spring Security 使用 Authentication 物件。每個 Authentication 物件包含一個主體和多個 GrantedAuthority 例項。為了方便在這些不同概念之間進行對映,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 實現。

DefaultJaasAuthenticationProvider

DefaultJaasAuthenticationProvider 允許將一個 JAAS Configuration 物件作為依賴注入。然後它使用注入的 JAAS Configuration 建立一個 LoginContext。這意味著 DefaultJaasAuthenticationProvider 不像 JaasAuthenticationProvider 那樣繫結到任何特定的 Configuration 實現。

InMemoryConfiguration

為了方便將 Configuration 注入到 DefaultJaasAuthenticationProvider 中,提供了一個名為 InMemoryConfiguration 的預設記憶體實現。該實現的建構函式接受一個 Map,其中每個鍵代表一個登入配置名稱,值代表一個 AppConfigurationEntry 例項的 Array。如果提供的 Map 中沒有找到對映,InMemoryConfiguration 還支援一個預設的 AppConfigurationEntry 物件 Array。詳細資訊請參見 InMemoryConfiguration 的 Javadoc。

DefaultJaasAuthenticationProvider 配置示例

雖然 InMemoryConfiguration 的 Spring 配置可能比標準的 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 的一個例項。做出此假設是為了嘗試更新 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>

作為 Subject 執行

如果配置了,JaasApiIntegrationFilter 會嘗試作為 JaasAuthenticationToken 上的 Subject 執行。這意味著可以使用以下方法訪問 Subject

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

您可以使用 jaas-api-provision 屬性配置此整合。此功能在與依賴於 JAAS Subject 被填充的遺留或外部 API 整合時非常有用。