Spring Integration 中的安全性
安全性是任何現代企業(或雲)應用中的重要功能之一。對於分散式系統(例如基於企業整合模式構建的系統)來說,這一點更為關鍵。訊息的獨立性和松耦合使得目標系統能夠透過訊息的 payload
中的任何型別的資料進行通訊。我們可以信任所有這些訊息,或者保護我們的服務免受“感染性”訊息的侵害。
從版本 6.3 開始,整個 spring-integration-security 模組已被移除,轉而支援更通用的 spring-security-messaging 庫提供的 API。 |
保護通道
為了保護整合流中的訊息通道,必須將 AuthorizationChannelInterceptor
新增到這些通道中,或者可以將其配置為具有相應模式的全域性通道攔截器。
-
Java
-
XML
@Bean
@GlobalChannelInterceptor(patterns = "secured*")
AuthorizationChannelInterceptor authorizationChannelInterceptor() {
return new AuthorizationChannelInterceptor(AuthorityAuthorizationManager.hasAnyRole("ADMIN", "PRESIDENT"));
}
<channel-interceptor pattern="securedChannel*">
<beans:bean class="org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor">
<beans:constructor-arg>
<beans:bean class="org.springframework.security.authorization.AuthorityAuthorizationManager"
factory-method="hasAnyRole">
<beans:constructor-arg>
<beans:array>
<beans:value>ADMIN</beans:value>
<beans:value>PRESIDENT</beans:value>
</beans:array>
</beans:constructor-arg>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
</channel-interceptor>
更多資訊請參閱全域性通道攔截器配置。
安全上下文傳播
為了確保我們與應用程式的互動是安全的,並且符合其安全系統規則,我們應該提供一些包含身份驗證(principal)物件的安全上下文。Spring Security 專案提供了一種靈活、規範的機制來透過 HTTP、WebSocket 或 SOAP 協議(透過簡單的 Spring Security 擴充套件,這也可以應用於任何其他整合協議)對應用程式客戶端進行身份驗證。它還提供了 SecurityContext
,用於對應用程式物件(例如訊息通道)進行進一步的授權檢查。預設情況下,SecurityContext
透過使用 (ThreadLocalSecurityContextHolderStrategy
) 繫結到當前 Thread
的執行狀態。透過對受保護方法的 AOP (面向切面程式設計) 攔截器來訪問它,以檢查(例如)呼叫的 principal
是否具有足夠的許可權來呼叫該方法。這在當前執行緒中執行良好。然而,通常處理邏輯可以在另一個執行緒、多個執行緒,甚至外部系統上執行。
如果應用程式構建在 Spring Integration 元件及其訊息通道之上,標準的執行緒繫結行為很容易配置。在這種情況下,受保護的物件可以是任何服務啟用器或轉換器,透過其 <request-handler-advice-chain>
中的 MethodSecurityInterceptor
(參見為端點新增行為)甚至 MessageChannel
(參見上文保護通道)進行保護。使用 DirectChannel
通訊時,SecurityContext
會自動可用,因為下游流在當前執行緒上執行。然而,對於 QueueChannel
、ExecutorChannel
和帶 Executor
的 PublishSubscribeChannel
,由於這些通道的特性,訊息會在一個執行緒與另一個執行緒(或多個執行緒)之間傳輸。為了支援這種情況,我們有兩種選擇:
-
在訊息頭中傳輸一個
Authentication
物件,並在受保護物件訪問之前在另一側提取並進行身份驗證。 -
將
SecurityContext
傳播到接收傳輸訊息的執行緒。
這在 spring-security-messaging
模組中實現為 org.springframework.security.messaging.context.SecurityContextPropagationChannelInterceptor
,可以將其新增到任何 MessageChannel
中,或配置為 @GlobalChannelInterceptor
。此攔截器的邏輯基於從當前執行緒(從 preSend()
方法)提取 SecurityContext
,並從 postReceive()
(beforeHandle()
) 方法將其填充到另一個執行緒。更多資訊請參閱 SecurityContextPropagationChannelInterceptor
的 Javadocs。
SecurityContext
的傳播和填充只是工作的一半。由於訊息不是訊息流中執行緒的所有者,並且系統必須確保其免受任何傳入訊息的侵害,因此必須從 ThreadLocal
中清理 SecurityContext
。SecurityContextPropagationChannelInterceptor
提供了 afterMessageHandled()
攔截器方法實現。它透過在呼叫結束時從傳播的 principal 中釋放執行緒來執行清理操作。這意味著,當處理移交訊息的執行緒完成訊息處理時(無論成功與否),上下文都會被清除,以防止在處理另一條訊息時被無意中使用。
當使用非同步閘道器時,您應該使用 Spring Security 併發支援中相應的
|