SAML2 认证集成
1. 前言
在前面的几个小节里,我们讨论了 Spring Security 如何集成 OAuth2.0 认证规范。本节我们讨论另一种统一认证方案「SAML2.0」。
SAML 全称 Security Assertion Markup Language,中文含义为安全断言标记语言,目前该语言规范已升级到 2.0 版本。
和 OAuth2.0 相比,SAML2.0 的设计更为全面,涵盖了联邦认证、身份管理、单点登录的总体标准(OAuth2.0 仅规定了开放授权规范,不处理身份验证)。
SAML 2.0 常用于大型企业内部的统一身份认证服务,而在互联网应用中很少出现。
本节重点讨论 Spring Security 集成 SAML 2.0 认证的方法。
本小节实例开发环境 :
本小节所使用的实例代码是基于 Spring 官网中提供的最小化 HelloWorld 模板创建,请点此下载完整的 HelloWorld 模板压缩包。
无
2. SAML 2.0 简介
SAML2.0 基于 XML 标准,核心目标是在不同安全域(Security Domain)之间交换认证和授权数据。
SAML2.0 的主要组成有:
- 服务提供者(SP):类似于 OAuth2.0 中的资源服务,用来提供真正的商业服务;
 - 身份鉴别者(IDP):提供用户的身份鉴别服务,确保用户的身份真实可信;
 - 断言消息(Assertions):用来描述认证的对象,比如用户认证的时间、方式、基本及扩展信息(如:email、电话等);
 - 协议(Protocol):是一系列的 Request 和 Response 对象的合集,代表着某个行为需要执行的操作序列;
 - 绑定(Binding):代表了 SAML 信息通过何种通讯协议被传输,比如 HTTP、HTTP-POST、SOAP等;
 - 元数据(MetaData):是 SAML 中的配置数据,比如 IP 地址、绑定类型等。
 
SAML 2.0 的认证过程如下:

3. SAML 2.0 认证集成
3.1 集成思路
SAML 2.0 认证登录,可以理解为 SP 从 IDP 获取 XML 格式断言消息的过程。目前有两种认证流程:
- 
IDP 端发起方式。首先用户直接在 IDP(例如 Okta 认证中心)登录,然后选择一个将要授权的 SP(例如 Web 应用),IDP 随后发送断言消息到 SP。
 - 
SP 发起方式。用户首先访问一个 SP,SP 向 IDP 发现认证请求,IDP 要求用户登录,如果登录成功,IDP 将发送断言消息到 SP。
 
当前 Spring Security 对 SAML 2.0 已支持的特性包括:
- 通过 
entityId = {baseUrl}/saml2/service-provider-metadata/{registrationId}形式声明 SP; - 通过 HTTP POST \ Redirect 方法,从 
{baseUrl}/login/saml2/sso/{registrationId}接收 SAML 响应中的认证断言; - 断言签名;
 - 支持断言内容加密;
 - 支持对 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 认证配置认证环境;
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .saml2Login() .relyingPartyRegistrationRepository(...) // 配置认证环境 ; }}
 
在 SAML 2.0 中,SP 和 IDP 都是作为可信成员,将其映射保存在 RelyingPartyRegistration 对象中,RelyingPartyRegistration 对象通过 HttpSecurity 实例中的 .saml2Login().relyingPartyRegistrationRepository() 方法实现其数值配置。
至此,最基础的 SAML 2.0 的认证配置就已经完成了。
3.3 配置 RelyingPartyRegistration
SAML 2.0 认证的核心配置项都存在于 RelyingPartyRegistration 对象中。
3.3.1 URI 模板配置
在 SAML 2.0 协议中,每次请求都会产生一个 URI 参数,在 saml2Login 过程中,URI 可以包含以下变量信息:
- baseUrl
 - registrationId
 - baseScheme
 - baseHost
 - basePort
 
使用举例如下:
{baseUrl}/login/saml2/sso/{registrationId}
3.3.2 可信成员配置
可信成员包含以下配置项:
registrationId,必填项,是当前配置项的唯一标识。localEntityIdTemplate,可选项,根据请求生成节点 ID 时所选用的模板。remoteIdpEntityId,必填项,IDP 的唯一标识。assertionConsumerServiceUrlTemplate,可选项,当由 SP 发起认证后,断言成功的返回地址模板。idpWebSsoUrl,必填项,IDP 做单点认证时的固定地址。credentials,凭证列表,包含用于签名、验签、加密、解密的证书。
3.3.3 从 SP 发起认证
从 SP 发起认证,最便捷的方法是访问以下地址:
{baseUrl}/saml2/authenticate/{registrationId}
终端被访问后,会通过调用 createAuthenticationRequest 方法生成 AuthNRequest 对象用于认证请求,如果需要对请求进行配置,可以增加通过如下方式:
public interface Saml2AuthenticationRequestFactory {
    String createAuthenticationRequest(Saml2AuthenticationRequest request);
}
4. 小结
本节我们讨论了 Spring Security 集成 SAML2.0 认证服务的方法,主要知识点有:
- Spring Security 在核心模块中已包含了 saml2Login 启动选项,可以用于构造 Saml 2.0 的 SP;
 - Spring Security 目前版本对 Saml 2.0 支持并不完整,但可以满足基本认证需求。
 
下节我们讨论 Spring Security 集成 CAS 认证的方法。
访问者可将本网站提供的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。
本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,邮箱:80764001@qq.com,予以删除。
