Run-As 身份驗證替換

AbstractSecurityInterceptor 能夠在安全物件回呼階段暫時替換 SecurityContextSecurityContextHolder 中的 Authentication 物件。這僅在原始 Authentication 物件已成功由 AuthenticationManagerAccessDecisionManager 處理後才會發生。RunAsManager 指示在 SecurityInterceptorCallback 期間應使用的替換 Authentication 物件(如果有的話)。

透過在安全物件回呼階段暫時替換 Authentication 物件,受保護的調用可以呼叫其他需要不同身份驗證和授權憑證的物件。它也可以針對特定的 GrantedAuthority 物件執行任何內部安全性檢查。由於 Spring Security 提供了許多輔助類別,可以根據 SecurityContextHolder 的內容自動組態遠端協定,因此當呼叫遠端 Web 服務時,這些 Run-As 替換特別有用。

組態

Spring Security 提供了一個 RunAsManager 介面

Authentication buildRunAs(Authentication authentication, Object object,
	List<ConfigAttribute> config);

boolean supports(ConfigAttribute attribute);

boolean supports(Class clazz);

第一個方法會傳回在方法調用期間應替換現有 Authentication 物件的 Authentication 物件。如果方法傳回 null,則表示不應進行替換。第二個方法由 AbstractSecurityInterceptor 用於其組態屬性的啟動驗證。安全性攔截器實作會呼叫 supports(Class) 方法,以確保已組態的 RunAsManager 支援安全性攔截器呈現的安全物件類型。

Spring Security 提供了一個 RunAsManager 的具體實作。如果任何 ConfigAttributeRUN_AS_ 開頭,則 RunAsManagerImpl 類別會傳回替換的 RunAsUserToken。如果找到任何此類 ConfigAttribute,則替換的 RunAsUserToken 包含與原始 Authentication 物件相同的主體、憑證和授權,以及每個 RUN_AS_ ConfigAttribute 的新 SimpleGrantedAuthority。每個新的 SimpleGrantedAuthority 都會加上前綴 ROLE_,後跟 RUN_AS ConfigAttribute。例如,RUN_AS_SERVER 會導致替換的 RunAsUserToken 包含 ROLE_RUN_AS_SERVER 授權。

替換的 RunAsUserToken 就像任何其他 Authentication 物件一樣。它需要由 AuthenticationManager 進行身份驗證,可能透過委派給合適的 AuthenticationProviderRunAsImplAuthenticationProvider 執行此類身份驗證。它接受呈現的任何有效的 RunAsUserToken

為了確保惡意程式碼不會建立 RunAsUserToken 並呈現它以保證被 RunAsImplAuthenticationProvider 接受,金鑰的雜湊會儲存在所有產生的權杖中。RunAsManagerImplRunAsImplAuthenticationProvider 是在 bean 環境中以相同的金鑰建立的

<bean id="runAsManager"
	class="org.springframework.security.access.intercept.RunAsManagerImpl">
<property name="key" value="my_run_as_password"/>
</bean>

<bean id="runAsAuthenticationProvider"
	class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider">
<property name="key" value="my_run_as_password"/>
</bean>

透過使用相同的金鑰,可以驗證每個 RunAsUserToken,因為它是由已核准的 RunAsManagerImpl 建立的。出於安全考量,RunAsUserToken 在建立後是不可變的。