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