亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

集成JAAS認證

1. 前言

在前面的小節中,我們相繼介紹了集中應用廣泛的統一身份認證規范:OAuth2.0,SAML2.0 和 CAS。本節我們介紹一種 Java 早期的安全框架,已經如何用 Spring Security 集成 JAAS。

JAAS 是「Java Authentication and Authorization Service」 的縮寫,其中文含義為「基于 Java 的認證和授權服務」。JAAS 提供了靈活的彈性的機制保護了 Java 客戶端程序和 Java 服務端程序的安全。

Spring Security 提供了 JAAS 的集成功能。

2. JAAS 基本原理

JAAS 是 Java 早期的安全框架,重點用于驗證代碼的來源或者開發者,避免代碼被偽造或遭到篡改。JAAS 主要用在 C / S 應用中,其驗證的對象是啟動程序的用戶。

JAAS 的特點是實現了「可插入認證」。應用程序與底層認證相互獨立,也就是說在調整底層認證方法的時候,不需要修改應用程序本身。應用程序通過配置文件,決定使用何種認證方法。

圖片描述

3. Spring Security 實現方法

Spring Security 對 JAAS 的支持主要包含如下幾個對象:

  • AbstractJaasAuthenticationProvider
  • DefaultJaasAuthenticationProvider
  • JaasAuthenticationProvider

我們對幾個對象逐一進行解讀。

3.1 AbstractJaasAuthenticationProvider

Spring Security 對 JAAS 認證的核心實現是 AbstractJaasAuthenticationProvider 類。它的核心行為是創建 LoginContext 對象。它還包括幾個重要的依賴注入項:JAAS CallbackHandlerJAAS AuthorityGranter。

3.1.1 JAAS CallbackHandler

大多數的 JAAS 認證模塊包含一系列有序的回調方法,這些回調方法通常用來維護用戶的認證信息。

在 Spring Security 項目開發中,當使用 JAAS 方式完成認證,Spring Security 的認證機制已經為 JAAS 登錄準備了足夠的認證信息,并將其保存為 Authentication 對象中。同時,Spring Security 為 JAAS 認證提供了兩個默認的回調接口:JaasNameCallbackHandlerJaasPasswordCallbackHandler。這兩個回調接口同時實現自 JaasAuthenticationCallbackHandler 接口。一般情況下,我們可以直接使用這些接口,而不用考慮實現細節。對于那些需要完全掌握回調行的開發者來說,抽象類 AbstractJaasAuthenticationProvider 為這些回調接口提供了一個基礎實現,即一個真正實現了 JAAS 回調接口的實現類,名為 InternalCallbackHandler。如果認證模塊向 InternalCallbackHandler 請求回調,回調會按順序調用 JaasAuthenticationCallbackHandler。

3.1.2 JAAS AuthorityGranter

JAAS 使用 Principal 身份主體作為鑒權依據,其角色信息包含在身份主體對象中。相對應的,Spring Security 的權限信息包含在 Authentication 對象中。每個 Authentication 對象都包含了單一的身份主體信息,和多個權限信息。為了匹配兩個不相同的權限模型,Spring Security 在 JAAS 認證模塊組件中,提供了 AuthorityGranter 接口。

AuthorityGranter 的作用是核實 JAAS 的身份主體,并返回一系列的表示權限信息的字符串。對每個返回的權限信息字符串,AbstractJaasAuthenticationProvider 都會創建一個 JaasGrantedAuthority 對象,時期包含權限信息和身份主體信息。這些信息在 JAAS LoginModule 首次認證通過后,由 AbstractJaasAuthenticationProvider 負責生成,并將其賦予到 LoginContext 實例中。我們可以通過LoginContext.getSubject().getPrincipals() 方式獲取身份信息和權限信息。

Spring Security 并未包含 AuthorityGranter 的具體實現,但是我們可以參考其單元測試中 TestAuthorityGranter 的方式進行擴展或自定義。

3.2 DefaultJaasAuthenticationProvider

DefaultJaasAuthenticationProvider 對象允許注入 JAAS 的相關配置,然后會用該配置創建 LoginContext 上下文,這意味著 DefaultJaasAuthenticationProvider 對象并未綁定任何的具體配置內容。

JAAS 的配置對象 Configuration 有一個簡單實現 InMemoryConfiguration,利用內存保存和獲取配置信息。在該類的構造方法里,我們可以將配置項以 Map 的形式逐一配置進來。

下面我們展示一個配置實例:使用 DefaultJaasAuthenticationProviderInMemoryConfiguration。

<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 是認證上下文的默認名稱
    -->
    <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>
    <!-- 這里可以配置我們自定義的 AuthorityGranter 實現 -->
    <bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
</list>
</property>
</bean>

3.3 JaasAuthenticationProvider

JaasAuthenticationProvider 的使用默認的配置對象創建上線文對象 LoginContext。

假設我們有一個 JAAS 認證的配置文件 /WEB-INF/login.conf,其內容如下

JAASTest {
    sample.SampleLoginModule required;
};

和眾多的 Spring Security bean 對象相同,JaasAuthenticationProvider 對象也通過 Spring 應用上下文配置,以下為通過 Spring 配置文件配置 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>

10.16.5. 啟動 Subject

如果配置完整,JaasApiIntegrationFilter 對象將在 JaasAuthenticationToken 對象中啟動主題對象 Subject,并可通過以下形式獲得:

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

這種集成方式可以通過 jaas-api-provision 屬性快速集成,當我們需要擴展 JAAS 主題時會被使用到。

4. 小結

本節的主要知識點如下:

  • JAAS 是 Java 原生支持的一種底層認證方式;
  • JAAS 認證的是應用程序的啟動用戶;
  • JAAS 認證與應用程序相互獨立;
  • Spring Security 為 JAAS 認證提供了代理接口和統一的配置方式。

JAAS 在現在的應用環境中已經非常少見了,不過作為 Java 早期的安全框架,它對我們理解 Java 應用認證和鑒權的邏輯很有幫助。下節我們介紹一個在互聯網環境下共享身份的解決方案:「OpenID」以及 Spring Security 與其集成的方法。