この記事を読むとできるようになること
- SPからIdPに送信する認証要求メッセージの用途と、主なタグ、属性について理解できる
- IdPからSPに送信する認証応答メッセージの用途と、主なタグ、属性について理解できる
認証要求メッセージ
全体像サンプル
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
Version="2.0"
IssueInstant="2024-03-21T00:46:40Z"
Destination="https://idp.com/sso/saml"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="https://sp.com/saml/acs/"
>
<saml:Issuer>https://sp.com/</saml:Issuer>
<samlp:NameIDPolicy
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
AllowCreate="true"
/>
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:20:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>
AuthnRequestタグ
<samlp:AuthnRequest
ID="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Version="2.0"
IssueInstant="2024-03-21T00:46:40Z"
Destination="https://idp.com/sso/saml"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="https://sp.com/saml/acs/"
>
・・・
</samlp:AuthnRequest>
属性名 | 内容 |
---|---|
ID | 認証要求メッセージ毎でユニークなID型のランダム文字列。SAML ResponseのInResponseTo属性と一致している必要がある |
Version | SAMLのバージョン |
IssueInstant | 認証要求メッセージの発行日時。ISO 8601形式のUTC日時形式 |
Destination | IdPが認証要求メッセージを受け取るエンドポイントURL |
ProtocolBinding | 認証応答メッセージを受け取る際の方法。HTTP-RedirectやHTTP-POSTがある |
AssertionConsumerServiceURL | SPが認証応答メッセージを受け取るエンドポイントURL |
Issuerタグ
<saml:Issuer>https://sp.com/</saml:Issuer>
属性名 | 内容 |
---|---|
Issuer | SPを一意に特定するためのユニークなID。別名「EntityID」。ドメイン名を含むURLであることが推奨されている |
NameIDPolicyタグ
<samlp:NameIDPolicy
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
AllowCreate="true"
/>
属性名 | 内容 |
---|---|
NameIDPolicy | 認証応答メッセージ内のユーザー識別子の形式。IdPで認証が成功するとNameIDを含む情報がSPに共有されるため、これを使用してSP側でも認証したりすることが可能 |
例えば、"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" は形式を特定しないことを示し、"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" は電子メールアドレス形式のNameIDを要求していることを表す
Signatureタグ
属性名 | 内容 |
---|---|
Signature | 認証要求メッセージに署名が行われる場合はこのタグが含まれる |
RequestedAuthnContext
IdP側でユーザーをどのように認証して欲しいかを指定する。例えば、PasswordProtectedTransportは、パスワードによる認証
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:20:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
メッセージ送信方法
HTTP-Redirectの場合を前提とする
- IdPのSSOエンドポイントURLにリダイレクトさせることで、IdPにメッセージを送信することができる
- SSOエンドポイントURLについて、例えばOktaなら、https://trial-XXXXXX.okta.com/app/trial-XXXXX_test_1/hogefoobar/sso/samlのような形式
- クエリパラメーターとして、パラメータ名には SAMLRequst を使用し、その内容として前述のAssertionConsumerServiceURLなどをエンコードしたものを付与する
- AuthnRequestをキャッシュされないように、以下のHTTPヘッダをレスポンスに含める必要がある
- Cache-Control: no-cache, no-storeまとめ
認証応答メッセージ
HTTP POST Bindingの場合を前提とする
- IdPは認証要求メッセージを受け取り、ユーザーを認証後、認証応答メッセージをSPに送信する
- 認証応答メッセージの内容は認証要求メッセージに比べて大きくURLに含めるのは難しいので、一般的にはHTTP POST Bindingが使用されるケースが多い
- IDPは秘密鍵を使用して認証応答メッセージにデジタル署名(=SignatureValue)を施し、公開鍵(X509Certificate)を含めて認証応答メッセージとして送信する
- SPは、認証応答メッセージを受け取り、検証した上で成功した場合は認証済みとする
- SPが メッセージを処理する際のルールはWeb Browser SSO Profileの4.1.4.3 < Response > Message Processing Rulesに定義されている
全体像サンプル
<saml2p:Response
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
Destination="http://sp.com/saml/acs/"
ID="id4644526104226571978328002"
InResponseTo="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
IssueInstant="2024-03-21T01:45:39.555Z"
Version="2.0"
>
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
>
http://idp.com/
</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id4644526104226571978328002">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="xs"
/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>eK1FdqPsFy2oi1WtfFy6L+DVI+Nhfn+/p5uHVMFan18=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>BWF・・・==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIID・・・</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
<saml2:Assertion
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
ID="id4644526105931911705028967"
IssueInstant="2024-03-21T01:45:39.555Z"
Version="2.0"
>
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
>
http://idp.com/
</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id4644526105931911705028967">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="xs"
/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>k/CgwMouTF3k3xr5neDmUJY9jinpL5AtenI4Qd2Sm4Q=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>UCCd・・・==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIID・・・</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">yamada@sample.co.jp</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData
InResponseTo="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
NotOnOrAfter="2024-03-21T01:50:39.555Z"
Recipient="https://sp.com/saml/acs/"
/>
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
NotBefore="2024-03-21T01:40:39.555Z"
NotOnOrAfter="2024-03-21T01:50:39.555Z"
>
<saml2:AudienceRestriction>
<saml2:Audience>https://sp.com/metadata</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
AuthnInstant="2024-03-21T01:45:38.890Z"
SessionIndex="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
>
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
<saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<saml2:Attribute
Name="email"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
>
<saml2:AttributeValue
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xs:string"
>
yamada@sample.co.jp
</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
</saml2:Assertion>
</saml2p:Response>
構成
多いので、主要なもののみ取り上げる。
Responseタグ
<saml2p:Response
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
Destination="https://sp.com/saml/acs/"
ID="id4644526104226571978328002"
InResponseTo="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
IssueInstant="2024-03-21T01:45:39.555Z"
Version="2.0"
>
・・・
</saml2p:Response>
属性名 | 内容 |
---|---|
Destination | SP側で認証応答メッセージを受け取るURL。認証要求メッセージのAssertionConsumerServiceURLと同一の値である必要がある |
ID | 一意のID |
InResponseTo | SPが送信した認証要求メッセージに対する認証応答メッセージであるかどうかを判定するための値。AuthnRequestのID属性と一致しているかどうかによって判定される |
IssueInstant | 認証応答メッセージが作成された時刻。ISO 8601形式のUTC日時の形式 |
Version | SAMLのバージョン |
Issuerタグ
IdPを一意に特定するためのユニークな値。別名「EntityID」。ドメイン名を含むURLであることが推奨されている
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
>
http://idp.com/
</saml2:Issuer>
Signatureタグ
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
・・・
<ds:SignatureValue>BWF・・・==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIID・・・</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
属性名 | 内容 |
---|---|
SignatureValue | 認証応答メッセージが送信元から受信者に送られる間に改ざんされていないこと、そしてメッセージが実際に主張する送信元から来たものであることを確認するために使用されるデジタル署名 |
X509Certificate | 公開鍵暗号方式における公開鍵の証明書。 (公開鍵証明書は、公開鍵の所有者の情報と公開鍵自体を含むデジタルドキュメントを指す) これを使用してSignatureValueを復号化し、その結果が認証応答のハッシュ値と一致することをすることで、IdPによって生成され、途中で改ざんされていないことが確認できる |
Statusタグ
認証要求メッセージに対する結果
<saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
StatusCode | 内容 備考 |
---|---|
Success | 成功 |
Requester | 認証要求を作成した側での原因による失敗 |
Responder | 認証応答を作成した側での原因による失敗 |
VersionMismatch | 認証要求と認証応答のSAMLのバージョンの違いによる失敗 |
Conditions | 認証応答メッセージの有効期間切れなどによる失敗 |
Assertionタグ
<saml2:Assertion
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
ID="id4644526105931911705028967"
IssueInstant="2024-03-21T01:45:39.555Z"
Version="2.0"
>
・・・
</saml2:Assertion>
属性名 | 内容 |
---|---|
ID | 一意のID |
IssueInstant | 認証応答メッセージが生成されたタイミングから成る。ISO 8601形式のUTC日時の形式 |
Version | SAMLのバージョン |
Subjectタグ
<saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">yamada@sample.co.jp</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData
InResponseTo="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
NotOnOrAfter="2024-03-21T01:50:39.555Z"
Recipient="https://sp.com/saml/acs/"
/>
</saml2:SubjectConfirmation>
</saml2:Subject>
属性名 | 内容 |
---|---|
Format | ログインを行うユーザーを識別するデータフォーマット(例: メールアドレス) |
InResponseTo | 認証要求メッセージのID属性と一致している必要がある |
NotOnOrAfter | 認証応答メッセージが有効な日時UTC(協定世界時)。この日時を過ぎると、認証応答メッセージは無効となり、検証失敗となる |
Recipient | 認証応答メッセージを送信するSPのエンドポイントURL |
AuthnStatementタグ
特定のユーザーが特定の時間に認証されたという事実を表す
<saml2:AuthnStatement
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
AuthnInstant="2024-03-21T01:45:38.890Z"
SessionIndex="ONELOGIN_2655fe95e153c480aa67aeafd6d64d453a5596c3"
>
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
属性名 | 内容 |
---|---|
AuthnInstant | ユーザーが認証された日時をUTC(協定世界時) |
AuthnContextClassRef | ユーザーが認証された方法。パスワード、二要素認証、バイオメトリクスなど。例えば、urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportはID/Passwordによる認証を表す |
まとめ
いかがでしたでしょうか。本記事では、SPとIdPでやり取りされる認証要求/認証応答メッセージの具体的な内容について紹介しました。次回のパートでは、Pythonを用いたsamlによるシングルサインオンの実装方法について紹介したいと思います。