SAML2.0

2023-03-22 11:12 星期三

协议概述

安全断言标记语言(Security Assertion Markup Language,SAML)是一个基于 XML 的开源标准数据格式,它在当事方之间交换身份验证和授权数据,尤其是在身份提供者和服务提供者之间交换。

名词解释

  • IdP:Identity Provider,身份提供者,SAML 规范定义的三个角色之一,通常指身份鉴别服务器。
  • SP:Service Providers,服务提供者,SAML 规范定义的三个角色之一。
  • Assert:断言,是指 IdP 认证用户后,发送认证结果给 SP的一种形式,包含认证用户的基本信息等。
  • SP ACS :Service Providers Assertion Consumer Service,服务提供者断言消费服务,用于接收IDP返回的 SAML 协议 XML 报文。
  • 元数据(MetaData):SAML 的元数据是配置数据,其包含关于 SAML 通信各方的信息,比如通信另一方的 ID、Web Service 的 IP 地址、所支持的绑定类型以及通信中实用的密钥等等。如下图所示:

登录流程

  1. 用户(User Agent)尝试登录 SP 提供的应用。
  2. SP 发现当前用户没有认证信息,需要进行身份认证,则生成一个 SAML 认证请求,并发送请求到 IdP元数据中的SingleSignOnService地址。
  3. 用户(User Agent)进行身份认证。
  4. IdP验证身份认证通过后,生成断言,断言可包括但不限于用户名、手机号码、邮箱等信息。
  5. IdP使用私钥对断言进行签名,然后将签名信息、用户信息等包装成特定 XML格式的返回报文,重定向 到SP ACS。
  6. SP使用Idp元数据中的X509Certificate公钥证书验证返回报文,并解析报文中的断言属性,验证用户名是否存在SP中,如存在,则登录成功,反之,提示相应错误。

开发详情

步骤1:

  • 引入SAML相关开发包,例如JAVA可考虑引入opensaml;
  • 将Idp的元数据文件导入到SP中进行解析,获取验签所需的证书和单点服务地址。

步骤2:

  • 用户请求SP并发现未登录,此时调用开发包API生成samlRequest参数,并重定向Idp的SAML地址。
 https://demo.cloudentify.com/api/authz/saml20/E67705501F0046EA7743?SAMLRequest=%samlRequest

步骤3:

  • SP提供ACS接口并接收SAMLResponse报文,调用开发包对SAMLResponse进行验签,验签成功后将得到断言信息。

SAMLResponse示例:

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNhbWwycDpSZXNwb25zZSBEZXN0aW5h
dGlvbj0iaHR0cHM6Ly9mdHNhZmUubXkuZnhpYW9rZS5jb20vc2FtbDIvc3Avc3NvL2xvZ2luIiBJRD0iRlRf
MTg3MjFkZjItMzY1Ny00MGVlLWExYjctNjRhZjIyOTUyMzhjIiBJc3N1ZUluc3RhbnQ9IjIwMjItMDQtMTRU MDM6MzU6NTAuNjA1WiIgVmVyc2lvbj0iMi4wIiB4bWxuczpzYW1sMnA9InVybjpvYXNpczpuYW1lczp0YzpT
QU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIj48
c2FtbDI6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6
ZW50aXR5IiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0
cDovL2Z0aWFtLmZ0c2FmZS5jb20uY24vYXBpPC9zYW1sMjpJc3N1ZXI+PGRzOlNpZ25hdHVyZSB4bWxuczpk
cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PGRzOlNpZ25lZEluZm8+PGRzOkNhbm9u
aWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMt
YzE0biMiLz48ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8w
OS94b0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9U5OVGNKRkFzT0h3Umh
VaUYybHZORXd5eGgwN1Jnbm9Vc09NNVAyRVpENEFWWHNndHJBNGZ4K0pxREovcXcza1lrbTgwV3c4ZAphVDV
5QmUrNXFzUG1xUDRXMnlPMWhzQ1BDaWplV29vMTdCT29aTnJwSU5xdXBzZzNDZWRSTWJuS1RLZTBDTEtPWXh
BV3NUR3hiclVWCk94TUJZMzg4bWduOURaUTJLSTQ1RVNJamFsd0FTN1ZmZjlkZ1Z5WWZDYitaQ1pSUFp5R2V
CRkl5REZtclcxa0NmSHBjb1MvTlArN2kKeDVORXRaZVZHeTFNOU9qaG1UK0JYRDlTckg0L0xx1mb3JaXM6bm
FtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm93NhbWwycDpSZXNwb25zZT4=

解析后得到示例:

  • saml2:Assertion节点,断言信息,包括 saml2:Subject、saml2:AttributeStatement 等子节点。
  • saml2:Subject 节点,为用户对应的应用帐号。
  • saml2:AttributeStatement 节点,为系统定义属性。系统定义属性,包括:
  • phonesn:用户手机号;
  • email: 用户邮箱;
  • username: 用户名;
  • online_ticket:当前登录用户身份标识(用于整个会话协议中唯一标识用户身份);
  • authorization:角色/资源授权信息,格式参考OIDC步骤4获取用户信息中的authorization。

登录态注销(退出登录):

  • 业务系统主动调用飞天云信注销登录状态。
HTTP Method:GET
https://demo.cloudentify.com/api/authz/logout/saml/{appkey}?SAMLRequest=%samlRequest&RelayState=123456

注:{appkey}为接入系统的唯一标识,需要从IAM获取。

1)飞天云信接收业务系统发来的SAML登出请求

请求参数:

  • SAMLRequest:SAML请求;
  • RelayState:随机数,如果业务系统存在登出地址,会回传回去。

%samlRequest示例值:

nZLBb4IwGMXv%2BytI7wUsILQRnIlZYuI0mW6HXUwpRdmgZXxl8c8f6JhuS3bYpYfmfb%2FX975OpseqtN5lA4VWMRrZLrKkEjor1D5Gj9s7HKFpcjMBXpWkZku91615kG%2BtBGPNu6NQ3JxGD8bUwBwnN8BzuW90W9tQcvFqC105ANrpGU55IiBrMY%2FRzhNRmvLcx1JmY%2BzLNMWchj7OCPe4GFGfC95JAVq5UGC4MjEiLiHYDTEZb12PuYR51CbR%2BBlZK23Wat3MciObXzr%2Fonsa0pI%2BbZdfATvni1HbKKY5FMAUryQwI9hmdr9knZTVjTZa6BIl5zrY6WHNNeFvAAeQTd8WSoa2BLHPhfUt2UKdSpo41%2FzBbdXxFvN%2Fub102zxwfXuxGizO0GTY70ZCX81CZfKY7EZZELo0oJh6IcF%2BEIQ4otLH3E9FSHIS0Ih%2Bgn6Mft1%2B%2BzDJBw%3D%3D

解析后得到如下示例内容:

Issuer:业务系统地址(请求来源地址)。

NameID:身份标识(将登录时获得的online_ticket放于此处)。

SessionIndex:Idp唯一值,请将单点登录时断言信息中SessionIndex值放置于此。

2)飞天云信成功解析请求后会回调通知业务系统提供的登出地址登出成功结果,通知以POST请求进行通知,请求参数为SAMLResponse。

HTTP Method:POST
http(s)://appdomain/uri?SAMLResponse=%samlResponse&RelayState=123456

请求参数:

  • SAMLResponse:SAML响应;
  • RelayState:业务系统请求时生成的随机数,此时回传回业务系统。

% samlResponse示例值:

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNhbWwycDpMb2dvdXRSZXNwb25zZSBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9zcC5mdHNhZmUuY29tL3NpZ25vdXQtc2FtbCIgSUQ9Il9mZWEwZDY4OS1lMDdiLTQ1YjEtODNmYy01MzE3MGYyZjg4ZDUiIEluUmVzcG9uc2VUbz0iX2JmNmRlNDRhLTllNmItNGNkYS1iOTgxLWJjNmUyMGE1YWFjZSIgSXNzdWVJbnN0YW50PSIyMDIyLTA3LTI2VDA2OjMzOjI5LjQwNFoiIFZlcnNpb249IjIuMCIgeG1sbnM6c2FtbDJwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPjxzYW1sMjpJc3N1ZXIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPmh0dHBzOi8vaWRwLmZ0c2FmZS5jb208L3NhbWwyOklzc3Vlcj48c2FtbDJwOlN0YXR1cz48c2FtbDJwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2FtbDJwOlN0YXR1cz48L3NhbWwycDpMb2dvdXRSZXNwb25zZT4%3D

解析后得到如下示例内容:

Issuer:云信业务地址。

Status:响应的退出结果(示例中表示成功)。

  • 业务系统被动等待飞天云信调用注销用户登录状态。

业务系统提供登出回调URL,接口描述如下:

HTTP Method:GET
http(s)://appdomain/uri?SAMLRequest=%samlRequest

注:http(s)://appdomain/uri 为业务系统提供。

%samlRequest解释同‘业务系统主动调用飞天云信注销登录状态’中一致。