定义
SAML(Security Assertion Markup Language)【1】,是一个开放标准数据格式,基于XML,用于在当事方之间交换身份验证和授权信数据,尤其是身份提供者(IdP
)和服务提供者(SP
)之间交换。目前最新的版本为SAML2.0。
场景
SAML解决的最重要的需求是网络浏览器的SSO。单点登录在内部网层面比较常见,例如甲骨文OAM就是基于Jakarta EE JaaS规范实现了domain内的SSO,使用Cookie对Session进行维护。但是将其扩展到内部网之外则一直存在问题。
参与角色
SAML定义了三个角色:委托人(principal
通常为一名用户),身份提供者(IdP
),服务提供者(SP
)。
principal
从SP
那里请求一项服务,SP
请求IdP
并从那里获得一个authentication assertion
。SP
可以基于这个assertion
进行存储控制的判断——即决定principal
是否有权执行某些服务。
在将assertion
发送给SP
之前,IdP
也可能向principal
要求一些信息——例如用户名和密码,以验证principal
的身份。
工作流程
1. 委托人通过HTTP user agent请求SP上的目标资源
https://sp.example.com/myresource
SP
为目标资源执行安全检查,如果在SP
上面已经存在了一个合法的安全上下文,跳过2-7。
2. 重定向到IdP上的SSO服务。
SP
决定了用户用哪一个IdP
,并将user agent
重定向到IdP
上的SSO服务。
https://idp.example.org/SAML2/SSO/Redirect?SAMLRequest=request
SAMLRequest 参数的值是经过Base64编码的压缩形式的<samlp:AuthnRequest> 元素。
3. 请求IdP上的SSO服务
user agent
向步骤2中的URL上的SSO服务发出一个GET请求。这个SSO服务处理 AuthnRequest (通过URL query参数SAMLRequest 发送来的),执行安全检查。如果用户没有一个有效的安全上下文,IdP
就认证这个用户。
4.回复是一个XHTML form
SSO服务通过一个包含XHTML form的文档,确认request和responds是有效的:
<form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...>
<input type="hidden" name="SAMLResponse" value="response" />
...
<input type="submit" value="Submit" />
</form>
SAMLResponse元素的值是经过Base64编码的< samlp:Response> 元素。
5. 请求SP上的Assertion消费服务
user agent
向SP
上的assertion消费服务发送一个POST。SAMLResponse 参数的值是从步骤4中的XHTML form里面得到的。
6. 重定向到目标资源
assertion消费服务处理response, 在SP
上创建一个安全上下文,并将user agent
重定向到目标资源。
7. 再次到SP上请求目标资源
user agent
再次到SP
上请求目标资源。
https://sp.example.com/myresource
8. 将请求的资源返回
此时一个安全上下文已经存在了,SP
将资源返回给user agent
.
同OAuth2/OIDC比较
解决浏览器单点登录问题的另一个方法是OpenID Connect协议(OAuth2/OIDC)。与OAuth2/OIDC相比,SAML较为简单,但是也有一些不足。首先,SAML将Token放在POST response的body部分,但是移动应用是不能访问HTTP POST response的body部分的。他们只能通过URL去获得Token,但是SAML是XML的形式,意味着URL可能会过长,从而使得移动应用无法读取SAML Token。
【1】SAML