Security Assertion Markup Language 2.0 (SAML 2.0)はsecurity domain間の認証と認可アイデンティティをやりとりするための SAML規格のバージョンである。SAML 2.0 は アサーション を含む セキュリティトークン を利用して、SAMLオーソリティ(アイデンティティプロバイダ)とSAMLコンシューマ(サービスプロバイダ)との間で本人(通常はエンドユーザ)に関する情報をやり取りするXML-ベースのプロトコルである。SAML 2.0はウェブベースのクロスドメインシングルサインオン (SSO) を可能にし、複数の認証トークンをユーザに配布する際の管理負荷を減らす。
SAML 2.0は、SAML 1.1に代わり、2005年3月にOASIS標準として承認された。SAML 2.0の重要な側面は、公式ドキュメントであるSAMLCore、 SAMLBind、 SAMLProf、、SAMLMetaに詳細に記載されている。
SAML 2.0の策定には、24以上の企業・団体から約30名が参加した。特筆すべきはLiberty AllianceがそのIDフェデレーション・フレームワーク(ID-FF)仕様をOASISに寄贈したことであり、これがSAML 2.0の仕様のベースとなった。したがって、SAML 2.0は、SAML 1.1、Liberty ID-FF 1.2、Shibboleth 1.3 が収れんしたものと言える。
SAML 2.0 アサーション
アサーションとは、SAMLオーソリティーが作成した 0 個以上のステートメントを提供する情報のパッケージである。SAML のアサーションは通常、<Subject> 要素で表されるサブジェクトについて行われる。SAML 2.0 仕様では、SAMLオーソリティーが作成できる 3 種類のアサーション・ステートメントを定義している。SAML で定義されたステートメントはすべて、サブジェクトに関連付けられている。 定義されている3種類のステートメントは以下のとおりである: 認証アサーション(Authentication Assertion):アサーション・サブジェクトは、特定の時間に特定の方法で認証された。 属性アサーション(Attribute Assertion): アサーション・サブジェクトは、提供された属性に関連付けられている。 認可決定アサーション(Authorization Decision Assertion):アサーション対象者が指定されたリソースにアクセスする許可を求める要求が、許可または拒否された。
SAML アサーションの重要なタイプは、Web ブラウザの SSO を促進するために使用される、いわゆる "bearer" アサーションである。
以下は、アイデンティティプロバイダ (https://idp.example.org/SAML2) からサービスプロバイダ (https://sp.example.com/SAML2)に対 して発行された短命のベアラ・アサーションの例である。このアサーションには、認証アサーション <saml:AuthnStatement> および属性アサーション<saml:AttributeStatement>の両方が含まれており、サービスプロバイダはこれらを使用してアクセス・コントロールの決定を行うはずである。接頭辞 saml:は、SAML V2.0アサーションの名前空間を表す。
SAMLの例 <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" Version="2.0" IssueInstant="2004-12-05T09:22:05Z"> <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"> 3f7b3dcf-1674-4ecd-92c8-1544f346baf8 </saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData InResponseTo="aaf23196-1773-2113-474a-fe114412ab72" Recipient="https://sp.example.com/SAML2/SSO/POST" NotOnOrAfter="2004-12-05T09:27:05Z"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2004-12-05T09:17:05Z" NotOnOrAfter="2004-12-05T09:27:05Z"> <saml:AudienceRestriction> <saml:Audience>https://sp.example.com/SAML2</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2004-12-05T09:22:00Z" SessionIndex="b07b804c-7c29-ea16-7300-4f3d6f7928ac"> <saml:AuthnContext> <saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> <saml:AttributeStatement> <saml:Attribute xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500" x500:Encoding="LDAP" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" FriendlyName="eduPersonAffiliation"> <saml:AttributeValue xsi:type="xs:string">member</saml:AttributeValue> <saml:AttributeValue xsi:type="xs:string">staff</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> </saml:Assertion>
なお、上記の例では、<saml:Assertion>要素に以下の子要素が含まれている:
<saml:Issuer>要素:アイデンティティプロバイダの一意の識別子を含む。 <ds:Signature>要素:<saml:Assertion>要素に対する整合性保持のデジタル署名(表示せず)を含む <saml:Subject>要素:認証されたプリンシパルを識別する。ただし、この場合、プライバシー保護の観点から、プリンシパルの身元は不透明な一時的な識別子で隠されてる。 <saml:Conditions> 要素:アサーションが「有効」とみなされる条件を示す。 <saml:AuthnStatement> 要素:IDプロバイダでの認証行為を記述する。 <saml:AttributeStatement> 要素:これは認証されたプリンシパルに関連する多値の属性を主張する。
言い換えれば、アサーションは以下の情報をエンコードしたものである:
サービスプロバイダ (https://sp.example.com/SAML2)専用のサブジェクト(3f7b3dcf-1674-4ecd-92c8-1544f346baf8)について、アサーション("b07b804c-7c29-ea16-7300-4f3d6f7928ac")が"2004-12-05T09:22:05Z"の時点でアイデンティティプロバイダ (https://idp.example.org/SAML2) によって発行された。
特に、認証ステートメントは以下のように主張している:
<saml:Subject> 要素で特定されたプリンシパルは、保護されたチャネル上で送信されたパスワードによって、"2004-12-05T09:22:00Z"の時点で認証された。
同様に、属性ステートメントは次のように主張する。
<saml:Subject>要素で特定されるプリンシパルは、この機関のスタッフである。
SAML 2.0 プロトコル
SAMLCoreでは以下のプロトコルが規定されている。
アサーションクエリおよびリクエストプロトコル 認証要求プロトコル Artifact Resolution Protocol 名前識別子管理プロトコル シングルログアウトプロトコル 名前識別子マッピングプロトコル
これらのプロトコルのうち、最も重要な「認証要求プロトコル」について、以下に詳しく説明する。
認証要求プロトコル
SAML 1.1 WebブラウザSSOプロファイルはIdentity Provider (IDP)によって開始(initiate)される。つまり、 一方的な<samlp:Response>要素がアイデンティティプロバイダから(ブラウザ経由で)サービスプロバイダに送信される。(接頭辞 samlp:はSAMLプロトコルの名前空間を示す。)
ただし、SAML 2.0 では、流れはサービスプロバイダから始まり、サービスプロバイダは アイデンティティプロバイダに明示的な認証要求を発行する。結果として生じる「認証要求プロトコル」は、SAML 2.0 の重要な新機能である。
プリンシパル(またはプリンシパルの代理を務めるエンティティ)が認証ステートメントを含むアサーションの取得を希望する場合、<samlp:AuthnRequest>要素がアイデンティティプロバイダに送信される: <samlp:AuthnRequest xmlns: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="2004-12-05T09:21:59Z" AssertionConsumerServiceIndex="0" AttributeConsumingServiceIndex="0"> <saml:Issuer>https://sp.example.com/SAML2</saml:Issuer> <samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/> </samlp:AuthnRequest> 上記の<samlp:AuthnRequest>要素は、暗黙的に 認証ステートメントを含むアサーションを要求するものであり、サービスプロバイダ (https://sp.example.com/SAML2) によって明確に発行され、その後(ブラウザを介して)アイデンティティプロバイダに提示された。 アイデンティティプロバイダは(必要であれば)プリンシパルを認証し、認証応答を発行する。認証応答は、(再びブラウザを介して)サービスプロバイダに送信される。
アーティファクト解決プロトコル
SAML メッセージは、あるエンティティから別のエンティティへ、「値」または「参照」によって送信される。SAML メッセージへの参照は「アーティファクト」と呼ばれる。 アーティファクトの受信者は、<samlp:ArtifactResolve> 要求をアーティファクトの発行者に直接送信することによって参照を解決し、発行者はアーティファクトによって参照される実際のメッセージで応答する。 たとえば、アイデンティティプロバイダが次の<samlp:ArtifactResolve> リクエストを(バック・チャネルを介して)サービスプロバイダに直接送信したとすると、次のようになる: <samlp:ArtifactResolve xmlns: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="2004-12-05T09:21:58Z"> <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer> <!-- an ArtifactResolve message SHOULD be signed --> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature> <samlp:Artifact>AAQAAMh48/1oXIM+sDo7Dh2qMp1HM4IF5DaRNmDj6RdUmllwn9jJHyEgIi8=</samlp:Artifact> </samlp:ArtifactResolve>
応答として、サービスプロバイダは、封入されたアーティファクトによって参照されるSAML要素を返す。 このプロトコルは、HTTP Artifact Bindingの基礎を形成している。
SAML 2.0バインディング
SAML 2.0 がサポートする「バインディング」の概要は、Bindings 仕様((SAMLBind)に記載されている:
SAML SOAP Binding (based on SOAP 1.1) Reverse SOAP (PAOS) Binding HTTP Redirect Binding HTTP POST Binding HTTP Artifact Binding SAML URI バインディング
Web ブラウザ SSO では、HTTP リダイレクト・バインディングと HTTP POST バインディングがよく使われる。 たとえば、サービスプロバイダは HTTP リダイレクトを使用して要求を送信する一方で、アイデンティティプロバイダは HTTP POST を使用して応答を送信することができる。 この例は、エンティティのバインディングの選択が、パートナーのバインディングの選択とは無関係で あることを示している。
HTTPリダイレクト・バインディング
SAML プロトコルメッセージは、HTTP GETリクエストのURLクエリ文字列で直接伝えることができる。URLの長さは実際には限られているので、HTTPリダイレクト・バインディングは、<samlp:AuthnRequest> メッセージなどの短いメッセージに適している。長いメッセージ(例えば、SAMLレスポンスのように、署名済みまたは暗号化されたSAMLアサーションを含むメッセージ)は、通常、 HTTP POSTバインディングのような他のバインディングを介して送信される。
HTTPリダイレクトで送信される SAMLリクエストまたはレスポンスには、それぞれSAMLRequest またはSAMLResponse クエリ文字列パラメータがある。メッセージは送信される前に、deflated (ヘッダーとチェックサムなし)、base64エンコード、URLエンコードが順に行われる。受信時には、元のメッセージを復元するために、このプロセスを逆に行う。
例えば、上記の <samlp:AuthnRequest>メッセージをエンコードすると、次のようになる:
https://idp.example.org/SAML2/SSO/Redirect?SAMLRequest=fZFfa8IwFMXfBb9DyXvaJtZ1BqsURRC2 Mabbw95ivc5Am3TJrXPffmmLY3%2FA15Pzuyf33On8XJXBCaxTRmeEhTEJQBdmr%2FRbRp63K3pL5rPhYOpkVdY ib%2FCon%2BC9AYfDQRB4WDvRvWWksVoY6ZQTWlbgBBZik9%2FfCR7GorYGTWFK8pu6DknnwKL%2FWEetlxmR8s BHbHJDWZqOKGdsRJM0kfQAjCUJ43KX8s78ctnIz%2Blp5xpYa4dSo1fjOKGM03i8jSeCMzGevHa2%2FBK5MNo1F dgN2JMqPLmHc0b6WTmiVbsGoTf5qv66Zq2t60x0wXZ2RKydiCJXh3CWVV1CWJgqanfl0%2Bin8xutxYOvZL18NK UqPlvZR5el%2BVhYkAgZQdsA6fWVsZXE63W2itrTQ2cVaKV2CjSSqL1v9P%2FAXv4C
上記のメッセージ(可読性のためにフォーマットされている)は、追加のセキュリティのために署名される場合もある。実際には、<samlp:AuthnRequest>に含まれるすべてのデータ(SP ID を含むIssuerやNameIDPolicyなど)は、事前に IdP と SP の間で(手動での情報交換や SAMLメタデータを介して)合意されている。その場合、リクエストへの署名はセキュリティ上の制約とはならない。<samlp:AuthnRequest>に、アサーション・コンシューマー・サービスのURLなど、IdPが事前に把握していない情報が含まれている場合、セキュリティの観点からリクエストへの署名が推奨される。
HTTP POSTバインディング
以下の例では、サービスプロバイダと アイデンティティプロバイダの両方が HTTP POST バインディングを使用している。最初に、サービスプロバイダはuser agent からの要求に、XHTML フォームを含むドキュメントで応答する。
<form method="post" action="https://idp.example.org/SAML2/SSO/POST" ...> <input type="hidden" name="SAMLRequest" value="''request''" /> ... その他のインプットパラメータ.... </form> SAMLRequestパラメータの値は、<samlp:AuthnRequest>要素のbase64エンコードであり、ブラウザ経由でアイデンティティプロバイダに送信される。アイデンティティプロバイダの SSO サービスは要求を検証し、別の XHTML フォームを含む文書で応答する: <form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...> <input type="hidden" name="SAMLResponse" value="''response''" /> ... </form>
SAMLResponseパラメータの値は、<samlp:Response>要素のbase64エンコーディングであり、同様にブラウザを介してサービスプロバイダに送信される。
フォームの送信を自動化するためには、次のようなJavaScriptの行をXHTMLページの任意の場所に加える: window.onload = function () { document.forms.submit(); }
これは、ページ内の最初のform要素に、上記のSAMLResponseを含むform要素(forms)が含まれていることを前提としている。
HTTP アーティファクト・バインディング
HTTP アーティファクトバインディングは、Artifact Resolution Protocolと SAML SOAP バインディング(HTTP上)を使用して、SAMLメッセージを参照により解決する。以下の具体例を考えてみる。サービスプロバイダが、アイデンティティプロバイダに<samlp:AuthnRequest> メッセージを送信したいとする。最初に、サービスプロバイダは、HTTPリダイレクトを介してアイデンティティプロバイダにアーティファクトを送信する。
https://idp.example.org/SAML2/SSO/Artifact?SAMLart=artifact
次に、アイデンティティプロバイダは、バック・チャネルを介してサービスプロバイダに直接<samlp:ArtifactResolve>リクエスト(先に示したArtifactResolveRequest など)を送信する。最後に、サービスプロバイダは、参照された<samlp:AuthnRequest>メッセージを含む<samlp:AuthnRequest> 要素を返す:
<samlp:ArtifactResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_d84a49e5958803dedcff4c984c2b0d95" InResponseTo="_cce4ee769ed970b501d680f697989d14" Version="2.0" IssueInstant="2004-12-05T09:21:59Z"> <!-- ArtifactResponseメッセージは署名されるべきである --> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <samlp:AuthnRequest xmlns: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="2004-12-05T09:21:59Z" Destination="https://idp.example.org/SAML2/SSO/Artifact" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" AssertionConsumerServiceURL="https://sp.example.com/SAML2/SSO/Artifact"> <saml:Issuer>https://sp.example.com/SAML2</saml:Issuer> <samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/> </samlp:AuthnRequest> </samlp:ArtifactResponse>
もちろん、フローは逆方向にも可能である。つまり、アイデンティティプロバイダはアーティファクトを発行することができ、実際にはこれがより一般的である。 たとえば、このトピックで後述する「double artifact」のプロファイル例を参照。
アーティファクトのフォーマット 一般に、SAML 2.0のアーティファクトは以下のように定義される(SAMLBind):
SAML_artifact := B64 (TypeCode EndpointIndex RemainingArtifact) TypeCode := Byte1Byte2 EndpointIndex := Byte1Byte2
したがって、SAML 2.0のアーティファクトは、2バイトのTypeCode、2バイトのEndpointIndex、およびRemainingArtifactと呼ばれる任意のバイト列の3つのコンポーネントから構成される。 これらの3つの情報は連結され、base64エンコードされて完全なアーティファクトとなる。
TypeCodeは、アーティファクトの形式を一意に識別する。 SAML 2.0では、このようなアーティファクトを1つだけ定義しており、タイプは 0x0004である。 EndpointIndexは、アーティファクトの発行者(前述のようにIdPまたはSPのいずれかである)が管理する特定のアーティファクト解決エンドポイントへの参照である。 RemainingArtifactは、タイプの定義によって決定され、アーティファクトの「肉」となるものである。
また、「type 0x0004 artifact」のフォーマットは以下のように定義される:
TypeCode := 0x0004 RemainingArtifact := SourceId MessageHandle SourceId := 20-byte_sequence MessageHandle := 20-byte_sequence
したがって、タイプ 0x0004のアーティファクトは、サイズが44 バイト(エンコードされていない)である。 SourceIdは任意のバイト列であるが、実際には、SourceIdは発行者のentityIDのSHA-1ハッシュである。 MessageHandleはランダムなバイト列で、アーティファクト発行者がオンデマンドで作成することを望んでいるSAMLメッセージを参照する。
例えば、この16進法のタイプ 0x0004のアーティファクトを考える:
00040000c878f3fd685c833eb03a3b0e1daa329d47338205e436913660e3e917549a59709fd8c91f2120222f