預認證場景

示例包括 X.509、Siteminder,以及應用程式執行所在的 Java EE 容器提供的認證。在使用預認證時,Spring Security 必須

  • 識別發出請求的使用者。

  • 獲取使用者的許可權。

具體細節取決於外部認證機制。在 X.509 的情況下,使用者可能透過其證書資訊識別;在 Siteminder 的情況下,則透過 HTTP 請求頭識別。如果依賴容器認證,則透過呼叫傳入 HTTP 請求上的 getUserPrincipal() 方法來識別使用者。在某些情況下,外部機制可能會提供使用者的角色和許可權資訊。然而,在其他情況下,您必須從單獨的源(例如 UserDetailsService)獲取許可權。

預認證框架類

由於大多數預認證機制遵循相同的模式,Spring Security 提供了一組類,為實現預認證提供程式提供了一個內部框架。這消除了重複,並允許以結構化的方式新增新的實現,而無需從頭開始編寫所有內容。如果您想使用諸如 X.509 認證之類的功能,則無需瞭解這些類,因為它已經提供了更易於使用和上手的名稱空間配置選項。如果您需要使用顯式 Bean 配置或計劃編寫自己的實現,則需要了解所提供實現的工作原理。您可以在 org.springframework.security.web.authentication.preauth 包下找到這些類。這裡我們只提供一個概述,因此您應在適當的情況下查閱 Javadoc 和原始碼。

AbstractPreAuthenticatedProcessingFilter

此類的作用是檢查安全上下文的當前內容,如果為空,則嘗試從 HTTP 請求中提取使用者資訊並將其提交給 AuthenticationManager。子類需要覆蓋以下方法來獲取這些資訊。

覆蓋 AbstractPreAuthenticatedProcessingFilter
  • Java

  • Kotlin

protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request);

protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request);
protected abstract fun getPreAuthenticatedPrincipal(request: HttpServletRequest): Any?

protected abstract fun getPreAuthenticatedCredentials(request: HttpServletRequest): Any?

呼叫這些方法後,過濾器會建立一個包含返回資料的 PreAuthenticatedAuthenticationToken,並將其提交以進行認證。這裡的“認證”實際上只是指進一步的處理,可能用於載入使用者的許可權,但遵循的是標準的 Spring Security 認證架構。

與其他 Spring Security 認證過濾器一樣,預認證過濾器有一個 authenticationDetailsSource 屬性,該屬性預設建立一個 WebAuthenticationDetails 物件,用於在 Authentication 物件的 details 屬性中儲存額外資訊,例如會話識別符號和原始 IP 地址。在可以從預認證機制獲取使用者角色資訊的情況下,資料也會儲存在此屬性中,其中 details 實現了 GrantedAuthoritiesContainer 介面。這使得認證提供程式能夠讀取外部分配給使用者的許可權。我們接下來看一個具體的例子。

J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource

如果過濾器配置了 authenticationDetailsSource(它是此類的例項),則透過對預定義的一組“可對映角色”中的每個角色呼叫 isUserInRole(String role) 方法來獲取許可權資訊。此類從配置的 MappableAttributesRetriever 中獲取這些角色。可能的實現包括在應用程式上下文中硬編碼列表以及從 web.xml 檔案中的 <security-role> 資訊中讀取角色資訊。預認證示例應用程式採用後一種方法。

還有一個額外的階段,透過使用配置的 Attributes2GrantedAuthoritiesMapper 將角色(或屬性)對映到 Spring Security GrantedAuthority 物件。預設情況下,它只是在名稱前新增常用的 ROLE_ 字首,但它讓您可以完全控制行為。

PreAuthenticatedAuthenticationProvider

預認證提供程式除了為使用者載入 UserDetails 物件外,幾乎沒有其他事情可做。它透過委託給 AuthenticationUserDetailsService 來完成此操作。後者類似於標準 UserDetailsService,但它接受一個 Authentication 物件,而不僅僅是使用者名稱

public interface AuthenticationUserDetailsService {
	UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException;
}

此介面可能還有其他用途,但對於預認證,它允許訪問我們上一節中看到的打包在 Authentication 物件中的許可權。PreAuthenticatedGrantedAuthoritiesUserDetailsService 類實現了這一點。另外,它也可以透過 UserDetailsByNameServiceWrapper 實現委託給標準的 UserDetailsService

Http403ForbiddenEntryPoint

AuthenticationEntryPoint 負責為未認證使用者(當他們嘗試訪問受保護資源時)啟動認證過程。然而,在預認證情況下,這不適用。只有當您不將預認證與其他認證機制結合使用時,才需要使用此類的例項配置 ExceptionTranslationFilter。如果使用者被 AbstractPreAuthenticatedProcessingFilter 拒絕,導致認證為空,則會呼叫它。如果被呼叫,它始終返回 403-forbidden 響應程式碼。

具體實現

X.509 認證在其單獨的章節中有所介紹。在這裡,我們介紹一些為其他預認證場景提供支援的類。

請求頭認證 (Siteminder)

外部認證系統可以透過在 HTTP 請求上設定特定的頭資訊嚮應用程式提供資訊。一個眾所周知的例子是 Siteminder,它在名為 SM_USER 的頭資訊中傳遞使用者名稱。這種機制由 RequestHeaderAuthenticationFilter 類支援,該類僅從頭資訊中提取使用者名稱。它預設使用 SM_USER 作為頭名稱。更多詳細資訊請參閱 Javadoc。

當使用這樣的系統時,框架根本不執行任何認證檢查,因此極其重要的是外部系統必須配置正確並保護對應用程式的所有訪問。如果攻擊者能夠在未被檢測到的情況下偽造其原始請求中的頭資訊,他們就有可能選擇任何他們希望的使用者名稱。

Siteminder 示例配置

以下示例展示了使用此過濾器的典型配置

<security:http>
<!-- Additional http configuration omitted -->
<security:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</security:http>

<bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="SM_USER"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
	<bean id="userDetailsServiceWrapper"
		class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
	<property name="userDetailsService" ref="userDetailsService"/>
	</bean>
</property>
</bean>

<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="preauthAuthProvider" />
</security:authentication-manager>

我們在這裡假設使用安全名稱空間進行配置。還假定您已將 UserDetailsService(稱為“userDetailsService”)新增到您的配置中以載入使用者的角色。

Java EE 容器認證

J2eePreAuthenticatedProcessingFilter 類從 HttpServletRequestuserPrincipal 屬性中提取使用者名稱。通常將此過濾器與 Java EE 角色的使用結合起來,如前面J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource 中所述。

程式碼庫中有一個使用這種方法的示例應用程式,如果您有興趣,可以從 Github 獲取程式碼並檢視應用程式上下文檔案。

© . This site is unofficial and not affiliated with VMware.