Masayan tech blog.

  1. ブログ記事一覧>
  2. SAMLによるシングルサインオン | 認証要求メッセージと認証応答メッセージ

SAMLによるシングルサインオン | 認証要求メッセージと認証応答メッセージ

公開日

この記事を読むとできるようになること

  • 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にメッセージを送信することができる
  • クエリパラメーターとして、パラメータ名には 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によるシングルサインオンの実装方法について紹介したいと思います。