zoukankan      html  css  js  c++  java
  • SAML2.0入门指南

    SAML,全称为Security Assertion Markup Language,是一种用于安全性断言的标记预压,目前的最新版本是2.0。原文地址
    本系列相关文章:
    OAuth2.0 协议入门指南
    OpenID Connect 协议入门指南
    OpenSAML示例

    SAML在单点登录中大有用处:在SAML协议中,一旦用户身份被主网站(身份鉴别服务器,Identity Provider,IDP)认证过后,该用户再去访问其他在主站注册过的应用(服务提供者,Service Providers,SP)时,都可以直接登录,而不用再输入身份和口令。

    SAML本身是一个很复杂的协议,这里只选取最重要的部分为大家讲解,更多细节请见官方文档,后续的文章也会进一步解析。

    SAML协议的核心是: IDP和SP通过用户的浏览器的重定向访问来实现交换数据。

    SP向IDP发出SAML身份认证请求消息,来请求IDP鉴别用户身份;IDP向用户索要用户名和口令,并验证其是否正确,如果验证无误,则向SP返回SAML身份认证应答,表示该用户已经登录成功了,此外应答中里还包括一些额外的信息,来却确保应答被篡改和伪造。

    下面我们以用户登录SP,SP向IDP发起请求来确认用户身份为例子,看看SAML的工作流程。比如SP是Google的Apps,IDP是一所大学的身份服务器,Alice是该大学的一名学生。

    现在Alice要通过浏览器查阅她的邮件,Alice一般会通过浏览器访问一个网页,比如https://mail.google.com/a/my-university.nl (step1)。因为这是个联合身份域,所以Google不会向用户索要用户名和密码,而是将其从定向到IDP来认证其身份(step3)。用户被重定向的URL类似于这种:
    https://idp.uni.nl/sso?
    SAMLRequest=fVLLTuswEN0j8Q…c%3D

    嵌入到HTTP请求中的SAMLRequest就是SAML认证请求消息。因为SAML是基于XML的(通常比较长),完整认证请求消息要经过压缩(为Url节省空间)和编码(防止特殊字符)才能传输。在压缩和编码之前,SAML消息有如下格式:

    <AuthnRequest  ID="kfcn...lfki" 
      Version="2.0" 
      IssueInstant="2013-02-05T08:28:50Z" 
      ProtocolBinding="urn:oasis:names:tc:SAML: 2.0:bindings:HTTP-POST" 
      ProviderName="google.com" 
      AssertionConsumerServiceURL="https://www.google.com/a/uni.nl/acs">
      <Issuer>google.com</Issuer>
      <NameIDPolicy  AllowCreate="true"
        Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>;
    </AuthnRequest>;

    上面的内容用最直白的方式解释出来就是:这个来自Google的请求,请验证当前用户的身份,并将结果返回。

    当IDP收到消息并确认要接受认证请求之后,就会要求Alice输入用户名和口令来验证其身份(如果Alice已经登录过了,就会跳过该步骤);当验证通过之后,Alice的浏览器将会跳转回Google的特定页面(AssertionConsumerService,简称ACS,step6)。同样,SAML身份认证响应的内容也是在压缩并编码后以参数的形式传输。在压缩和编码之前,其结构类如下:

    <Response Version="2.0" 
      IssueInstant="2013-02-05T08:29:00Z" 
      Destination="https://www.google.com/a/my.uni.nl/acs" InResponseTo="kfcn...lfki">   
      <Issuer>https://idp.uni.nl/</Issuer>   
      <Status>
        <StatusCode   
          Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> 
      </Status> 
      <Assertion Version="2.0" 
        IssueInstant="2013-02-05T08:29:00Z">     
        <Issuer>https://idp.uni.nl/</Issuer>   
        <Subject> 
          <NameID>alice</NameID>   
          <SubjectConfirmation ...> 
            <SubjectConfirmationData 
              NotOnOrAfter="2013-02-05T08:34:00Z"   
              Recipient="https://www.google.com/a/my.uni.nl/acs" InResponseTo="kfcn...lfki"/>  
            </SubjectConfirmation> 
        </Subject> 
        <Conditions NotBefore="2013-02-05T08:28:30Z" NotOnOrAfter="2013-02-05T08:34:00Z"> 
        </Conditions> 
        <AuthnStatement 
          AuthnInstant="2013-02-05T08:29:00Z" 
          SessionNotOnOrAfter="2013-02-05T16:29:00Z> 
        </AuthnStatement> 
      </Assertion>
     </Response>

    虽然内容很多,但是其主要表达的是:该消息来自idp.uni.nl,名为Alice用户的身份已经被我验证,该消息的有效期为2分钟。此外,重定向的URL中还要有该消息的签名以保证其不备篡改,验证签名的公钥和算法,都是IDP和SP提前协商好的。

    当Google接受到SAML认证响应之后,会首先验证消息的签名是否正确(step7)以及是否因超时而失效。然后再从认证消息中提取出Google能识别用户身份(NameID,即Alice),如果以上的步骤都是顺利的,用户将会成功登陆Google(Step8)。

    为了便于解释,以上例子中的信息都保持了可读性,如果想要去看看真实的SAML信息,建议推荐使用火狐浏览器的插件工具 SAML tracer。该插件将会在浏览器中添加一个窗口来显示SAML消息,以下是截图:

    希望以上的内容能帮助你理解SAML协议。SAML协议的内容十分复杂,但是涉及到单点登录的内容都是以上述内容为基础的。

    更多关于SAML协议的是实现的内容,请参见本人编写的一系列教程文章来介绍如何使用OpenSAML,欢迎阅读指正:

    扩展阅读

    1. OAuth2.0 协议入门指南
    2. OpenID Connect 协议入门指南

    作者:登高且赋

    链接:https://www.jianshu.com/p/636c1ee16eba/
  • 相关阅读:
    剑气之争,聊聊算法岗位的门户之见!
    80%学生的困惑,学完C/C++之后学什么?
    算法工程师日常,训练的模型翻车了怎么办?
    迭代器设计模式,帮你大幅提升Python性能
    十年编程经验总结,三点技巧帮你提升代码能力!
    CenterNet:Corner-Center三元关键点,检测性能全面提升 | ICCV 2019
    CornerNet:经典keypoint-based方法,通过定位角点进行目标检测 | ECCV2018
    阿里面试:MySQL如何设计索引更高效?
    大厂是怎么进行SQL调优的?
    程序人生|从网瘾少年到微软、BAT、字节offer收割机逆袭之路
  • 原文地址:https://www.cnblogs.com/wpcnblog/p/12718249.html
Copyright © 2011-2022 走看看