快速理解SAML2.0
SAML,全称为Security Assertion Markup Language,是一种用于安全性断言的标记语言,目前的最新版本是2.0。
它是一个基于XML的标准,用于在不同的安全域(security domain)之间交换认证和授权数据。SAML2.0可以帮助我们跨域实现单点登录。
术语介绍
-
服务提供方(Service Provider,简称SP),服务提供的实体。举个例子,我们平时使用邮件服务、腾讯云、腾讯会议等软件服务,这类都是服务提供方。
-
身份提供方(Identity Provider,简称IDP),身份提供的实体,包含对用户进行身份验证的能力。当我们使用企业微信扫码的登录腾讯会议的时候,这里的企业微信其实就可以理解为身份提供方。在SAML协议里,严格规范了IDP和SP之间传输的Token格式。
-
SAML请求(SAMLRequest),由SP生成,发送给IDP的身份验证请求,所以一般也叫做AuthnRequest(Authentication Request)。
-
SAML响应(SAMLResponse),由IDP生成,携带用户身份信息,发送给SP的身份验证结果,所以一般也叫做SAMLAssertion。
-
服务提供方发起(SP-initiated),表示整个认证流程是由SP发起的,当客户直接访问SP的资源或网站时,跳转到IDP再跳转回来的过程,我们就称这个过程是SP-initiated的单点登录。
-
认证提供方发起(IDP-initiated),表示整个认证流程是由IDP发起的,IDP直接提供SAML响应给到SP方,验证用户身份。
SAML认证流程
下面介绍的是一个SP-initiated的完整认证流程,IDP-initiated可以理解为是SP-initiated的简化部分。
-
用户打开SP地址,如访问腾讯云。
-
SP接收到请求之后,携带SAMLRequest请求到到IDP处(SAMLRequest的格式后面会给出)。
-
IDP接收到SAMLRequest后,会在IDP验证用户身份,玉符统一身份会检查当前用户是否登录,如果未登录跳转登录页面。
-
IDP验证身份通过后,会重定向到SP,携带SAMLResponse(SAMLResponse的格式后面会给出)。
-
SP验证SAMLResponse,验证通过后取出SAMLResponse里携带的用户信息,访问对应的用户。
SAMLRequest介绍
下面是一个SAMLRequest的XML示例
1<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://www.sp.com/saml/acs" Destination="https://www.idp.com/saml/authn" ForceAuthn="false" ID="_7xvtiohf7xupg9ulo8an1g4bemeranpifvup" IsPassive="false" IssueInstant="2019-07-25T09:59:02.467Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">2 <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://www.sp.com</saml2:Issuer>3</saml2p:AuthnRequest>
SAMLRequest通常以saml2p:AuthnRequest
作为XML顶层的名称,配合一些属性描述
-
xmlns:saml2p
一般固定为urn:oasis:names:tc:SAML:2.0:protocol
-
AssertionConsumerServiceURL
表示服务提供方SP接受SAML断言响应的接口地址,如此处例子中的https://www.sp.com/saml/acs -
Destination
表示身份提供方IDP接受SAML请求的地址,如此处的https://www.idp.com/saml/authn -
saml2:Issuer
表示发起SAML请求的服务提供方SP的身份,此处示例为https://www.sp.com
在实际请求中,还需要将SAMLReqeust进行Base64编码,上文示例的SAMLRequest进行Base64编码之后如下:
1fZFBT8JAEIXvJv6Hzd5pSwPWbigJSowkGhuoHryYpQywSTu77uwWfr6lYISYcJ158+bNNyOSdRUbMfFui3P49kCO7esKSRw7GfcWhZakSKCsgYQrxWLy+iLiIBLGaqdLXXE2IQLrlMZHjeRrsAuwjSrhff6S8a1zhkQY7na7gExQ6jo8uIeyJM6m7UqF8jB7qVSrc+khIGdP2pbQhc34WlYEnM2mGf9K9k1rsF0ne282qa/0vcT+ZrCENolEo9aNN62UckmkGvgbJvIwQ3ISXcbjqJ/2oqQXD4soFcNURHEwuEs+OctPhz4oXCncXKeyPIpIPBdF3svfFgVnH2Cpu7AV8PHtDWOjDrDoEthz5tfN5S9oPv6PdRSem7ZrToXLB49/AA==
当服务提供方SP未登录时,需要跳转到认证提供方IDP的地址,进行身份验证操作,最终生成的URL如下所示:
1https://www.idp.com/saml/authn?SAMLRequest=fZFBT8JAEIXvJv6Hzd5pSwPWbigJSowkGhuoHryYpQywSTu77uwWfr6lYISYcJ158+bNNyOSdRUbMfFui3P49kCO7esKSRw7GfcWhZakSKCsgYQrxWLy+iLiIBLGaqdLXXE2IQLrlMZHjeRrsAuwjSrhff6S8a1zhkQY7na7gExQ6jo8uIeyJM6m7UqF8jB7qVSrc+khIGdP2pbQhc34WlYEnM2mGf9K9k1rsF0ne282qa/0vcT+ZrCENolEo9aNN62UckmkGvgbJvIwQ3ISXcbjqJ/2oqQXD4soFcNURHEwuEs+OctPhz4oXCncXKeyPIpIPBdF3svfFgVnH2Cpu7AV8PHtDWOjDrDoEthz5tfN5S9oPv6PdRSem7ZrToXLB49/AA==
SAMLResponse介绍
当IDP接受到服务提供方SP发起的SAMLRequest时,会在IDP的域内进行身份认证操作,完成登录行为之后,会携带当前登录的用户身份,发送SAMLResponse给到服务提供方SP。
下面是一个SAMLResponse的XML示例
1<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://www.sp.com/saml/acs" ID="_80ff50f0-73e9-4357-934e-15939aa197ae" InResponseTo="_7xvtiohf7xupg9ulo8an1g4bemeranpifvup" IssueInstant="2019-07-25T09:59:01.653Z" Version="2.0">2 <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://www.idp.com</saml2:Issuer>3 <saml2p:Status>4 <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>5 </saml2p:Status>6 <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_ee51e413-cb8c-4cff-a833-8e5ab5a65712" IssueInstant="2019-07-25T09:59:01.653Z" Version="2.0">7 <saml2:Issuer>https://www.idp.com</saml2:Issuer>8 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">9 <ds:SignedInfo>10 <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>11 <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>12 <ds:Reference URI="#_ee51e413-cb8c-4cff-a833-8e5ab5a65712">13 <ds:Transforms>14 <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>15 <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>16 </ds:Transforms>17 <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>18 <ds:DigestValue>SeLenKpDFTFSrd4RodgCxUbXi1I=</ds:DigestValue>19 </ds:Reference>20 </ds:SignedInfo>21 <ds:SignatureValue>fEN31jRzjpGPSFEazXSYIu8mlhSrB/2rhlGmkQw8vbgUlHveU4BfX91knG11yF4HcLd5686WYWCS9P9szLvcxuQlVi1z5NiIFs967Z3hCZuU6mP86/5qEJVOVeUnaS39YtP8Jwxoev2d4QJjJ0+9+9ifOQkf4bhM+9b8Q1/3A5Q4xqjvArHTwGQMnjpi5hJQprkreChvNXGu3vemzHb5HEGkQHsbwavuA65VDwQ3sxdQbbDjQrXMIZWlKt51IXHhDVrlCwVIDXPCrN1e3wJrkLPitAUbhDCcRdVvmc8a5lcmvX4SkDn7PwzmFAf1rXACCyvKft5YycYnN7zHkymLCA==</ds:SignatureValue>22 <ds:KeyInfo>23 <ds:X509Data>24 <ds:X509SubjectName>C=CN,L=Beijing,CN=com,CN=yufuid</ds:X509SubjectName>25 <ds:X509Certificate>MIIC/DCCAeSgAwIBAgIIBjRkHLoMipUwDQYJKoZIhvcNAQEFBQAwPjEPMA0GA1UEAwwGeXVmdWlkMQwwCgYDVQQDDANjb20xEDAOBgNVBAcMB0JlaWppbmcxCzAJBgNVBAYTAkNOMB4XDTE5MDcyMzEwNDA1NloXDTIwMDcyMjEwNDA1NlowPjEPMA0GA1UEAwwGeXVmdWlkMQwwCgYDVQQDDANjb20xEDAOBgNVBAcMB0JlaWppbmcxCzAJBgNVBAYTAkNOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0dk/S9XEiBio3CRccVIsjFX4KBGZPfz47jrm9TF1v3t+7Cy7WkYD6EW/rQYi7ORfRTVx8m8UsiB04MjwHARtVdDPP9COxfjkVp5h5nQv1P6WYtZjIFDiIBbS0of1YmeHzCixxGQDk+PL/M19aey9DoRVg9MjcQYppjoiYbJhqj/YL2kCO5QgaquPptBCVKcMpqE1BCggPLyH3M1V7/QJXzRKBs/iOO/3yUnapftK/ysZeWMZ2hEGlB/AW3OP9pO2vijONqxbHqTFyngyYof+QRl7F5KsmZNP5Pd6SoYo0MtrEsDVIchdx9Mb1iCLZfiHqbq8s4mr7+alvuyBE1lW+QIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAdz05eOepSmE+IFMdwLkkD5oDBBwC16ie5BpXBxFAYxEYrQ8sZPmjTIhG+tQe3lnkxmrgyPbq1pevybGl3aR9dPWysg3ps2pK+pJQt6aRHQbNhy+fFT4uqZzVXy/61LPt8OhhhzjGVoApIh53A4OuffV2B1PueBChjrrKEZGHk5iVuzv1kEtGu0NIKbTXBcG7ZfX+2pKYYKw3AKllFDSBL/ePFjUh5iXJWwwGflqwtQjmZYZt4k+UMDIW7L6r5FlDNc4JGjH1gWOXpCZ6EkGR1rAmK2Fnv1/5LTRVYrMlGYlCx29DhM7GVnpgfTmua15E3dW+WyS4TOM8UnjavAIBa</ds:X509Certificate>26 </ds:X509Data>27 </ds:KeyInfo>28 </ds:Signature>29 <saml2:Subject>30 <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">sanzhang</saml2:NameID>31 <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">32 <saml2:SubjectConfirmationData InResponseTo="_7xvtiohf7xupg9ulo8an1g4bemeranpifvup" NotOnOrAfter="2019-07-25T10:04:01.647Z" Recipient="https://www.sp.com/saml/acs"/>33 </saml2:SubjectConfirmation>34 </saml2:Subject>35 <saml2:Conditions NotBefore="2019-07-25T09:54:01.647Z" NotOnOrAfter="2019-07-25T10:04:01.647Z">36 <saml2:AudienceRestriction>37 <saml2:Audience>https://www.sp.com</saml2:Audience>38 </saml2:AudienceRestriction>39 </saml2:Conditions>40 <saml2:AuthnStatement AuthnInstant="2019-07-25T09:59:01.653Z">41 <saml2:AuthnContext>42 <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef>43 </saml2:AuthnContext>44 </saml2:AuthnStatement>45 </saml2:Assertion>46</saml2p:Response>
这里的参数比较多,就不一一介绍了,只标记几个关键字段进行解释:
-
这里的
Destination
其实表示的是服务提供方SP接收SAML响应的地址,如示例的https://www.sp.com/saml/acs
。注意一定要跟SAMLRequest里的Destination
区分开来。 -
NameID
表示登录的用户身份,这里的响应表示登录的用户为sanzhang。 -
SAMLResponse是会指定有效期的,用
NotBefore
和NotOnOfAfter
进行表示,上述示例中,该响应的有效期为2019年7月25日9点54分到2019年7月25日10点54分(北京时间需要增加八小时)。
SAML如何保证响应的有效性
身份提供方IDP需要生成密钥对,用密钥对生成配套的证书,并将证书给到服务提供方SP。SP需要存储证书,当IDP签发SAMLResponse时,会对Response响应进行签名,当SP接受到IDP签发的SAMLResponse时,需要用证书校验签名的有效性。