安全声明标记语言SAML2.0初探
文章目錄
- 簡介
- SAML的構成
- SAML的優勢
- SAML是怎么工作的
- SP redirect request; IdP POST response
- SP POST Request; IdP POST Response
- SP redirect artifact; IdP redirect artifact
- 總結
簡介
SAML的全稱是Security Assertion Markup Language, 是由OASIS制定的一套基于XML格式的開放標準,用在身份提供者(IdP)和服務提供者 (SP)之間交換身份驗證和授權數據。
SAML的一個非常重要的應用就是基于Web的單點登錄(SSO)。
接下來我們一起來看看SAML是怎么工作的。
SAML的構成
在SAML協議中定義了三個角色,分別是principal:代表主體通常表示人類用戶。identity provider (IdP)身份提供者和service provider (SP)服務提供者。
IdP的作用就是進行身份認證,并且將用戶的認證信息和授權信息傳遞給服務提供者。
SP的作用就是進行用戶認證信息的驗證,并且授權用戶訪問指定的資源信息。
SAML的優勢
為什么要使用SAML呢?
第一可以提升用戶體驗,如果系統使用SAML,那么可以在登錄一次的情況下,訪問多個不同的系統服務。這實際上也是SSO的優勢,用戶不需要分別記住多個系統的用戶名和密碼,只用一個就夠了。
第二可以提升系統的安全性,使用SAML,我們只需要向IdP提供用戶名密碼即可,
第三用戶的認證信息不需要保存在所有的資源服務器上面,只需要在在IdP中存儲一份就夠了。
SAML是怎么工作的
接下來,我們通過一個用SAML進行SSO認證的流程圖,來分析一下SAML是怎么工作的。
根據請求方式有redirect和post的不同,使用SAML來進行SSO認證有通常有三種方式,我們一一道來。
SP redirect request; IdP POST response
上圖中User Agent就是web瀏覽器,我們看一下如果用戶想請求Service Provider的資源的時候,SAML協議是怎么處理的。
SP將會對該資源進行相應的安全檢查,如果發現已經有一個有效的安全上下文的話,SP將會跳過2-7步,直接進入第8步。
RelayState是SP維護的一個狀態信息,主要用來防止CSRF攻擊。
其中這個SAMLRequest是用Base64編碼的samlp:AuthnRequest,下面是一個samlp:AuthnRequest的例子:
<samlp:AuthnRequestxmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"ID="aaf23196-1773-2113-474a-fe114412ab72"Version="2.0"IssueInstant="2020-09-05T09:21:59Z"AssertionConsumerServiceIndex="0"AttributeConsumingServiceIndex="0"><saml:Issuer>https://sp.flydean.com/SAML2</saml:Issuer><samlp:NameIDPolicyAllowCreate="true"Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/></samlp:AuthnRequest>為了安全起見,SAMLRequest還可以使用SP提供的簽名key來進行簽名。
IdP收到這個AuthnRequest請求之后,將會進行安全驗證,如果是合法的AuthnRequest,那么將會展示登錄界面。
這個form中包含了SAMLResponse信息,SAMLResponse中包含了用戶相關的信息。
同樣的SAMLResponse也是使用Base64進行編碼過的samlp:Response。
<samlp:Responsexmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"ID="identifier_2"InResponseTo="identifier_1"Version="2.0"IssueInstant="2020-09-05T09:22:05Z"Destination="https://sp.flydean.com/SAML2/SSO/POST"><saml:Issuer>https://idp.flydean.com/SAML2</saml:Issuer><samlp:Status><samlp:StatusCodeValue="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertionxmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"ID="identifier_3"Version="2.0"IssueInstant="2020-09-05T09:22:05Z"><saml:Issuer>https://idp.flydean.com/SAML2</saml:Issuer><!-- a POSTed assertion MUST be signed --><ds:Signaturexmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature><saml:Subject><saml:NameIDFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">3f7b3dcf-1674-4ecd-92c8-1544f346baf8</saml:NameID><saml:SubjectConfirmationMethod="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationDataInResponseTo="identifier_1"Recipient="https://sp.flydean.com/SAML2/SSO/POST"NotOnOrAfter="2020-09-05T09:27:05Z"/></saml:SubjectConfirmation></saml:Subject><saml:ConditionsNotBefore="2020-09-05T09:17:05Z"NotOnOrAfter="2020-09-05T09:27:05Z"><saml:AudienceRestriction><saml:Audience>https://sp.flydean.com/SAML2</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatementAuthnInstant="2020-09-05T09:22:00Z"SessionIndex="identifier_3"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion></samlp:Response>我們可以看到samlp:Response中包含有saml:Assertion信息。
user agent 收到XHTML form之后將會提交該form給SP。
SP中的assertion consumer service將會處理這個請求,創建相關的安全上下文,并將user agent重定向到要訪問的資源頁面。
user agent再次請求SP資源。
因為安全上下文已經創建完畢,SP可以直接返回相應的資源,不用再次到IdP進行認證。
我們可以看到上面的所有的信息交換都是由前端瀏覽器來完成的,在SP和IdP之間不存在直接的通信。
這種全部由前端來完成信息交換的方式好處就是協議流非常簡單,所有的消息都是簡單的GET或者POST請求。
如果為了提高安全性,也可以使用引用消息。也就是說IdP返回的不是直接的SAML assertion,而是一個SAML assertion的引用。SP收到這個引用之后,可以從后臺再去查詢真實的SAML assertion,從而提高了安全性。
SP POST Request; IdP POST Response
剛剛講的是SP redirect Request,這里我們看一下SP POST request是怎么做的:
和第一種方式的不同之處在于第二步和第三步。
第二步:SP不再進行redirect了,而是返回一個XHTML form給User agent:
<form method="post" action="https://idp.flydean.com/SAML2/SSO/POST" ...><input type="hidden" name="SAMLRequest" value="request" /><input type="hidden" name="RelayState" value="token" />...<input type="submit" value="Submit" /></form>第三步:拿到第二步的XHTML form之后,User agent將該form post到IdP SSO server。
從第四步開始就和第一種方式是一樣的了。
SP redirect artifact; IdP redirect artifact
第三種方式,SP和IdP都用的是redirect,但是redirect的內容都是artifact。
之前我們講了SAML message可以以值的方式也可以以引用的方式來進行傳遞。
而這種以引用的傳遞方式就是artifact。
收到artifact的receiver會發送一個samlp:ArtifactResolve 給issuer,從而獲得真正的message。
下面是一個向IdP請求message的例子:
<samlp:ArtifactResolvexmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"ID="_cce4ee769ed970b501d680f697989d14"Version="2.0"IssueInstant="2020-09-05T09:21:58Z"><saml:Issuer>https://idp.flydean.com/SAML2</saml:Issuer><!-- an ArtifactResolve message SHOULD be signed --><ds:Signaturexmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature><samlp:Artifact>AAQAAMh48/1oXIM+sDo7Dh2qMp1HM4IF5DaRNmDj6RdUmllwn9jJHyEgIi8=</samlp:Artifact></samlp:ArtifactResolve>相應的server會返回一個包含samlp:AuthnRequest的samlp:ArtifactResponse:
<samlp:ArtifactResponsexmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"ID="_d84a49e5958803dedcff4c984c2b0d95"InResponseTo="_cce4ee769ed970b501d680f697989d14"Version="2.0"IssueInstant="2020-09-05T09:21:59Z"><!-- an ArtifactResponse message SHOULD be signed --><ds:Signaturexmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature><samlp:Status><samlp:StatusCodeValue="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><samlp:AuthnRequestxmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"ID="_306f8ec5b618f361c70b6ffb1480eade"Version="2.0"IssueInstant="2020-09-05T09:21:59Z"Destination="https://idp.flydean.com/SAML2/SSO/Artifact"ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"AssertionConsumerServiceURL="https://sp.flydean.com/SAML2/SSO/Artifact"><saml:Issuer>https://sp.flydean.com/SAML2</saml:Issuer><samlp:NameIDPolicyAllowCreate="false"Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/></samlp:AuthnRequest></samlp:ArtifactResponse>看下第三種方式的流程圖:
可以看到這種方式和前面兩種方式的區別就是多了一個請求真實message的步驟。
以第三,四,五步為例:
第三步user agent請求IdP的SSO server:
https://idp.example.org/SAML2/SSO/Artifact?SAMLart=artifact_1&RelayState=token注意這里請求的參數變成了SAMLart。
第四步,IdP需要發送一個samlp:ArtifactResolve到SP來請求真正的samlp:AuthnRequest。
第五步,SP返回一個samlp:ArtifactResponse 包含samlp:AuthnRequest。
總結
SAML協議和它的基本用法就是上面這樣。下面的文章我們會舉一個具體的例子,來講解如何應用SAML協議。
本文作者:flydean程序那些事
本文鏈接:http://www.flydean.com/saml-startup/
本文來源:flydean的博客
歡迎關注我的公眾號:「程序那些事」最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
總結
以上是生活随笔為你收集整理的安全声明标记语言SAML2.0初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Tomcat Native提升Tom
- 下一篇: SSO的通用标准OpenID Conne