SAML2 認證集成
1. 前言
在前面的幾個小節(jié)里,我們討論了 Spring Security 如何集成 OAuth2.0 認證規(guī)范。本節(jié)我們討論另一種統(tǒng)一認證方案「SAML2.0」。
SAML 全稱 Security Assertion Markup Language,中文含義為安全斷言標記語言,目前該語言規(guī)范已升級到 2.0 版本。
和 OAuth2.0 相比,SAML2.0 的設計更為全面,涵蓋了聯(lián)邦認證、身份管理、單點登錄的總體標準(OAuth2.0 僅規(guī)定了開放授權規(guī)范,不處理身份驗證)。
SAML 2.0 常用于大型企業(yè)內(nèi)部的統(tǒng)一身份認證服務,而在互聯(lián)網(wǎng)應用中很少出現(xiàn)。
本節(jié)重點討論 Spring Security 集成 SAML 2.0 認證的方法。
本小節(jié)實例開發(fā)環(huán)境:
本小節(jié)所使用的實例代碼是基于 Spring 官網(wǎng)中提供的最小化 HelloWorld 模板創(chuàng)建,請點此下載完整的 HelloWorld 模板壓縮包。
2. SAML 2.0 簡介
SAML2.0 基于 XML 標準,核心目標是在不同安全域(Security Domain)之間交換認證和授權數(shù)據(jù)。
SAML2.0 的主要組成有:
- 服務提供者(SP):類似于 OAuth2.0 中的資源服務,用來提供真正的商業(yè)服務;
- 身份鑒別者(IDP):提供用戶的身份鑒別服務,確保用戶的身份真實可信;
- 斷言消息(Assertions):用來描述認證的對象,比如用戶認證的時間、方式、基本及擴展信息(如:email、電話等);
- 協(xié)議(Protocol):是一系列的 Request 和 Response 對象的合集,代表著某個行為需要執(zhí)行的操作序列;
- 綁定(Binding):代表了 SAML 信息通過何種通訊協(xié)議被傳輸,比如 HTTP、HTTP-POST、SOAP等;
- 元數(shù)據(jù)(MetaData):是 SAML 中的配置數(shù)據(jù),比如 IP 地址、綁定類型等。
SAML 2.0 的認證過程如下:
3. SAML 2.0 認證集成
3.1 集成思路
SAML 2.0 認證登錄,可以理解為 SP 從 IDP 獲取 XML 格式斷言消息的過程。目前有兩種認證流程:
-
IDP 端發(fā)起方式。首先用戶直接在 IDP(例如 Okta 認證中心)登錄,然后選擇一個將要授權的 SP(例如 Web 應用),IDP 隨后發(fā)送斷言消息到 SP。
-
SP 發(fā)起方式。用戶首先訪問一個 SP,SP 向 IDP 發(fā)現(xiàn)認證請求,IDP 要求用戶登錄,如果登錄成功,IDP 將發(fā)送斷言消息到 SP。
當前 Spring Security 對 SAML 2.0 已支持的特性包括:
- 通過
entityId = {baseUrl}/saml2/service-provider-metadata/{registrationId}
形式聲明 SP; - 通過 HTTP POST \ Redirect 方法,從
{baseUrl}/login/saml2/sso/{registrationId}
接收 SAML 響應中的認證斷言; - 斷言簽名;
- 支持斷言內(nèi)容加密;
- 支持對 Name ID 元素進行加密;
- 支持將認證斷言的屬性轉換為
Converter<Assertion, Collection<? extends GrantedAuthority>>
對象; - 允許使用
GrantedAuthoritiesMapper
管理權限白名單; - 使用
java.security.cert.X509Certificate
公鑰格式; - SP 通過
AuthNRequest
初始化認證流程。
3.2 代碼集成
- 開啟
saml2Login()
支持;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.saml2Login() // 啟動 SAML2 認證支持
;
}
}
- 為 SAML 2.0 認證配置認證環(huán)境;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.saml2Login()
.relyingPartyRegistrationRepository(...) // 配置認證環(huán)境
;
}
}
在 SAML 2.0 中,SP 和 IDP 都是作為可信成員,將其映射保存在 RelyingPartyRegistration
對象中,RelyingPartyRegistration
對象通過 HttpSecurity
實例中的 .saml2Login().relyingPartyRegistrationRepository()
方法實現(xiàn)其數(shù)值配置。
至此,最基礎的 SAML 2.0 的認證配置就已經(jīng)完成了。
3.3 配置 RelyingPartyRegistration
SAML 2.0 認證的核心配置項都存在于 RelyingPartyRegistration
對象中。
3.3.1 URI 模板配置
在 SAML 2.0 協(xié)議中,每次請求都會產(chǎn)生一個 URI 參數(shù),在 saml2Login
過程中,URI 可以包含以下變量信息:
- baseUrl
- registrationId
- baseScheme
- baseHost
- basePort
使用舉例如下:
{baseUrl}/login/saml2/sso/{registrationId}
3.3.2 可信成員配置
可信成員包含以下配置項:
registrationId
,必填項,是當前配置項的唯一標識。localEntityIdTemplate
,可選項,根據(jù)請求生成節(jié)點 ID 時所選用的模板。remoteIdpEntityId
,必填項,IDP 的唯一標識。assertionConsumerServiceUrlTemplate
,可選項,當由 SP 發(fā)起認證后,斷言成功的返回地址模板。idpWebSsoUrl
,必填項,IDP 做單點認證時的固定地址。credentials
,憑證列表,包含用于簽名、驗簽、加密、解密的證書。
3.3.3 從 SP 發(fā)起認證
從 SP 發(fā)起認證,最便捷的方法是訪問以下地址:
{baseUrl}/saml2/authenticate/{registrationId}
終端被訪問后,會通過調(diào)用 createAuthenticationRequest
方法生成 AuthNRequest
對象用于認證請求,如果需要對請求進行配置,可以增加通過如下方式:
public interface Saml2AuthenticationRequestFactory {
String createAuthenticationRequest(Saml2AuthenticationRequest request);
}
4. 小結
本節(jié)我們討論了 Spring Security 集成 SAML2.0 認證服務的方法,主要知識點有:
- Spring Security 在核心模塊中已包含了 saml2Login 啟動選項,可以用于構造 Saml 2.0 的 SP;
- Spring Security 目前版本對 Saml 2.0 支持并不完整,但可以滿足基本認證需求。
下節(jié)我們討論 Spring Security 集成 CAS 認證的方法。