天天看點

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是該大學的一名學生。

image.png

現在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. OpenSAML 使用引導 I : 簡介
  2. OpenSAML 使用引導 II : Service Provider 的實作之AuthnRequest
  3. OpenSAML 使用引導 III: Service Provider 的實作之Artifact與斷言
  4. OpenSAMl 使用引導IV: 安全特性

擴充閱讀

繼續閱讀