SAML,全稱為Security Assertion Markup Language,是一種用于安全性斷言的標(biāo)記預(yù)壓,目前的最新版本是2.0。原文地址
本系列相關(guān)文章:
OAuth2.0 協(xié)議入門指南
OpenID Connect 協(xié)議入門指南
OpenSAML示例
SAML在單點登錄中大有用處:在SAML協(xié)議中,一旦用戶身份被主網(wǎng)站(身份鑒別服務(wù)器,Identity Provider,IDP)認(rèn)證過后,該用戶再去訪問其他在主站注冊過的應(yīng)用(服務(wù)提供者,Service Providers,SP)時,都可以直接登錄,而不用再輸入身份和口令。
SAML本身是一個很復(fù)雜的協(xié)議,這里只選取最重要的部分為大家講解,更多細(xì)節(jié)請見官方文檔,后續(xù)的文章也會進(jìn)一步解析。
SAML協(xié)議的核心是: IDP和SP通過用戶的瀏覽器的重定向訪問來實現(xiàn)交換數(shù)據(jù)。
SP向IDP發(fā)出SAML身份認(rèn)證請求消息,來請求IDP鑒別用戶身份;IDP向用戶索要用戶名和口令,并驗證其是否正確,如果驗證無誤,則向SP返回SAML身份認(rèn)證應(yīng)答,表示該用戶已經(jīng)登錄成功了,此外應(yīng)答中里還包括一些額外的信息,來卻確保應(yīng)答被篡改和偽造。
下面我們以用戶登錄SP,SP向IDP發(fā)起請求來確認(rèn)用戶身份為例子,看看SAML的工作流程。比如SP是Google的Apps,IDP是一所大學(xué)的身份服務(wù)器,Alice是該大學(xué)的一名學(xué)生。
現(xiàn)在Alice要通過瀏覽器查閱她的郵件,Alice一般會通過瀏覽器訪問一個網(wǎng)頁,比如https://mail.google.com/a/my-university.nl (step1)。因為這是個聯(lián)合身份域,所以Google不會向用戶索要用戶名和密碼,而是將其從定向到IDP來認(rèn)證其身份(step3)。用戶被重定向的URL類似于這種:
https://idp.uni.nl/sso?
SAMLRequest=fVLLTuswEN0j8Q…c%3D
嵌入到HTTP請求中的SAMLRequest就是SAML認(rèn)證請求消息。因為SAML是基于XML的(通常比較長),完整認(rèn)證請求消息要經(jīng)過壓縮(為Url節(jié)省空間)和編碼(防止特殊字符)才能傳輸。在壓縮和編碼之前,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>;
上面的內(nèi)容用最直白的方式解釋出來就是:這個來自Google的請求,請驗證當(dāng)前用戶的身份,并將結(jié)果返回。
當(dāng)IDP收到消息并確認(rèn)要接受認(rèn)證請求之后,就會要求Alice輸入用戶名和口令來驗證其身份(如果Alice已經(jīng)登錄過了,就會跳過該步驟);當(dāng)驗證通過之后,Alice的瀏覽器將會跳轉(zhuǎn)回Google的特定頁面(AssertionConsumerService,簡稱ACS,step6)。同樣,SAML身份認(rèn)證響應(yīng)的內(nèi)容也是在壓縮并編碼后以參數(shù)的形式傳輸。在壓縮和編碼之前,其結(jié)構(gòu)類如下:
<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>
雖然內(nèi)容很多,但是其主要表達(dá)的是:該消息來自idp.uni.nl,名為Alice用戶的身份已經(jīng)被我驗證,該消息的有效期為2分鐘。此外,重定向的URL中還要有該消息的簽名以保證其不備篡改,驗證簽名的公鑰和算法,都是IDP和SP提前協(xié)商好的。
當(dāng)Google接受到SAML認(rèn)證響應(yīng)之后,會首先驗證消息的簽名是否正確(step7)以及是否因超時而失效。然后再從認(rèn)證消息中提取出Google能識別用戶身份(NameID,即Alice),如果以上的步驟都是順利的,用戶將會成功登陸Google(Step8)。
為了便于解釋,以上例子中的信息都保持了可讀性,如果想要去看看真實的SAML信息,建議推薦使用火狐瀏覽器的插件工具 SAML tracer。該插件將會在瀏覽器中添加一個窗口來顯示SAML消息,以下是截圖:
希望以上的內(nèi)容能幫助你理解SAML協(xié)議。SAML協(xié)議的內(nèi)容十分復(fù)雜,但是涉及到單點登錄的內(nèi)容都是以上述內(nèi)容為基礎(chǔ)的。
更多關(guān)于SAML協(xié)議的是實現(xiàn)的內(nèi)容,請參見本人編寫的一系列教程文章來介紹如何使用OpenSAML,歡迎閱讀指正: