LOCKED
ブログ一覧に戻る
SSO・IDaaSLOCKED MSO

SAML 2.0仕様の要点【NameID FormatとBinding方式】

関連トピック: SAML認証の実装ガイド【仕様から設定まで完全解説】

SAML 2.0は、XMLで認証情報を受け渡すための業界標準です。異なる組織やドメインのあいだで「このユーザーは認証済みである」という事実を、改ざんを検知できる形で伝える役目を持ちます。

ここでは実装や連携設定のときに実際に参照することになる部分を、仕様のどこに書かれているかとあわせて整理します。扱うのはAssertionの構造、NameID Formatの種類、Binding方式、署名と暗号化、そしてメタデータ交換です。

SAML 2.0はどんな規格か

SAML 2.0は2005年3月にOASISの標準仕様として承認されました。それ以前はSAML 1.1、Liberty AllianceのID-FF 1.2、Shibboleth 1.3が併存していましたが、SAML 2.0はこの3つを一本に統合したものです。現在の企業向けSSOはここを土台にしています。

認証情報を発行する側をIdP(Identity Provider)、それを受け取ってユーザーをログインさせる側をSP(Service Provider)と呼びます。IdPが署名付きのXML文書を発行し、ブラウザがそれをSPへ運び、SPが署名を検証してセッションを張る。これがSAML 2.0の骨格です。

仕様書は役割ごとに4本に分かれています。確認したい内容がどれに載っているかを知っておくと、調べ物の時間が縮みます。

仕様書扱う内容参照したい場面
Core (saml-core-2.0-os)Assertionの構造、AuthnRequest・Responseの要素、NameID Format、ステータスコード要素や属性の意味を確認する
Bindings (saml-bindings-2.0-os)HTTP-POST・HTTP-Redirectなど転送方式送信方法やエンコードを確認する
Profiles (saml-profiles-2.0-os)Web Browser SSOなど利用パターンごとの必須条件SSOとして成立する条件を確認する
Metadata (saml-metadata-2.0-os)EntityDescriptorなど設定情報の交換形式IdPとSPの設定交換でつまずいたとき
RFPテンプレート(無料)

IDaaS導入RFPテンプレート

IDaaS導入の社内稟議に使えるRFPテンプレート。SSO、MFA、プロビジョニングなどの要件を網羅したフォーマットです。

無料でダウンロード

SAML 2.0の基本構成:Assertion・Protocol・Binding

SAML 2.0は、3つの主要コンポーネントから構成されます。

1. Assertion(アサーション)

AssertionはSAML認証の中核であり、ユーザー認証情報を表現するXML文書です。

<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
  Version="2.0"
  ID="_d71a3a8e9ee6e4fd0b3b1f9c0e8e5c7b"
  IssueInstant="2024-03-06T10:30:00Z">

  <saml:Issuer>https://idp.example.com</saml:Issuer>

  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <!-- XML署名 -->
  </ds:Signature>

  <saml:Subject>
    <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
      user@example.com
    </saml:NameID>
    <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
      <saml:SubjectConfirmationData NotOnOrAfter="2024-03-06T11:30:00Z"
        Recipient="https://sp.example.com/acs"/>
    </saml:SubjectConfirmation>
  </saml:Subject>

  <saml:Conditions NotBefore="2024-03-06T10:25:00Z"
    NotOnOrAfter="2024-03-06T11:30:00Z">
    <saml:AudienceRestriction>
      <saml:Audience>https://sp.example.com</saml:Audience>
    </saml:AudienceRestriction>
  </saml:Conditions>

  <saml:AuthnStatement AuthnInstant="2024-03-06T10:30:00Z"
    SessionIndex="s23bdf1f8e9e2e3c5d4f9a1b2c3d4e5f6">
    <saml:AuthnContext>
      <saml:AuthnContextClassRef>
        urn:oasis:names:tc:SAML:2.0:ac:classes:Password
      </saml:AuthnContextClassRef>
    </saml:AuthnContext>
  </saml:AuthnStatement>

  <saml:AttributeStatement>
    <saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
      <saml:AttributeValue>user@example.com</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="givenName">
      <saml:AttributeValue>太郎</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="sn">
      <saml:AttributeValue>山田</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>

Assertion内の主要要素:

必須かどうかはスキーマ上の定義ではなくProfileで決まります。以下の「扱い」は、もっとも使われるWeb Browser SSO Profileでの位置づけです。

要素説明Web Browser SSOでの扱い
IssuerIdPのエンティティID必要
Subject認証対象ユーザーの識別子必要
SubjectConfirmationMethod に bearer を指定し、Recipient と NotOnOrAfter で使用範囲を限定する必要
ConditionsAudienceRestriction で受け取るべきSPを限定し、NotBefore / NotOnOrAfter で有効期間を示す必要
AuthnStatement認証時刻・方式(パスワード、多要素認証など)必要
AttributeStatementユーザー属性(メールアドレス、部門など)任意

2. Protocol(プロトコル)

ProtocolはAssertion交換の手順を定義します。

AuthnRequest:SPからIdPへ送信される認証要求

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
  ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd"
  Version="2.0"
  IssueInstant="2024-03-06T10:30:00Z"
  Destination="https://idp.example.com/sso"
  AssertionConsumerServiceURL="https://sp.example.com/acs">

  <saml:Issuer>https://sp.example.com</saml:Issuer>

  <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    AllowCreate="true"/>
</samlp:AuthnRequest>

Response:IdPからSPへ返信される認証応答

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd"
  Version="2.0"
  IssueInstant="2024-03-06T10:31:00Z"
  Destination="https://sp.example.com/acs"
  InResponseTo="_8e8dc5f69a98cc4c1ff3427e5ce34606fd">

  <saml:Issuer>https://idp.example.com</saml:Issuer>

  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  </samlp:Status>

  <saml:Assertion>
    <!-- Assertion本体 -->
  </saml:Assertion>
</samlp:Response>

NameID Formatの種類と使い分け

NameIDはAssertionの中でユーザーを指す識別子です。その値をどう解釈するかをFormat属性が示します。IdPが送るFormatとSP側の設定が食い違うと、認証そのものは成功しているのにSPがユーザーを特定できず、ログインに失敗します。連携作業でつまずきやすいのはここです。

Core仕様の8.3節が定義するFormatは8種類です。このURIはAssertionの<NameID>に付くほか、AuthnRequestの<NameIDPolicy>や<Issuer>のFormat属性にも同じものを使います。まず8種類を押さえておくと切り分けが早くなります。

FormatURI値の意味
unspecifiedurn:oasis:names:tc:SAML:1.1:nameid-format:unspecified解釈をIdPとSPの取り決めに委ねる
emailAddressurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressメールアドレス形式。RFC 2822のaddr-spec(local-part@domain)で、表示名・コメント・山かっこは付けない。SaaS連携で最も使われる
X509SubjectNameurn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectNameX.509証明書のサブジェクト名。XML署名仕様の<ds:X509SubjectName>と同じ書き方で、RFC 2253の規則とは異なる
WindowsDomainQualifiedNameurn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedNameDomainName\UserName の形。ドメイン名と区切りの \ は省略してもよい
kerberosurn:oasis:names:tc:SAML:2.0:nameid-format:kerberosKerberosのプリンシパル名。name[/instance]@REALM の形
entityurn:oasis:names:tc:SAML:2.0:nameid-format:entitySAMLのエンティティ自体を指す。1,024文字以内のURIで、NameQualifier・SPNameQualifier・SPProvidedIDは付けない。個人ユーザーには使わない
persistenturn:oasis:names:tc:SAML:2.0:nameid-format:persistentIdPと、SPまたはSPの連合(affiliation)の組み合わせごとに固定される仮名。実際のユーザー名などから推測できない値で生成する。256文字以内
transienturn:oasis:names:tc:SAML:2.0:nameid-format:transientそのセッションだけで有効な一時的な値。256文字以内

persistentとtransientの違いは、SP側でユーザーを継続的に紐づけられるかどうかです。persistentは同じユーザーなら毎回同じ値になるためSP側のアカウントと1対1で対応づけられますが、その値はSPごとに別々に発行されるので、通常は複数のSPが持ち寄って照合しても同一人物だとは分かりません。ただし仕様はSPの連合(affiliation)単位での発行も認めているため、その構成では加盟するSPが同じ識別子を共有し、連合の内側では突き合わせが成立します。名寄せを避けたいなら、ここを確認します。transientは毎回変わります。SPが受け取るのは「認証済みの誰かである」という事実だけです。なお仕様はpersistentをプライバシー保護の仕組みと位置づけていて、識別子を共有した相手以外への平文での受け渡しを禁じ、ログへの出力も相応の管理なしには認めていません。どちらを選ぶかは運用方針の話になるので、SAML統合ベストプラクティスで規模別の考え方を扱っています。

NameIDFormatが出てくる3か所

同じFormatのURIが、メタデータ・AuthnRequest・Assertionの3か所に別々の意味で現れます。どれを直せばよいかはここで決まります。

出てくる場所書き方意味
IdP / SPのメタデータ<NameIDFormat> 要素自分が対応できる形式の宣言。複数並べられる
AuthnRequest<NameIDPolicy> の Format 属性SPからIdPへの「この形式で返してほしい」という要求
Assertion<NameID> の Format 属性IdPが実際に発行した値の形式

メタデータの宣言は対応表であって、要求でも結果でもありません。SP側の管理画面で選んだ形式が応答に反映されないときは、AuthnRequestが別のFormatを要求していないか、IdPがその要求をどう解釈したかを先に見ます。

NameIDPolicyで要求する

SPからIdPへ「この形式で返してほしい」と伝えるのがAuthnRequest内のNameIDPolicy要素です。

<samlp:NameIDPolicy
  Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
  SPNameQualifier="https://sp.example.com"
  AllowCreate="true"/>

Formatに要求する形式のURIを指定し、SPNameQualifierでその識別子をどのSPに向けて発行するかを示します。IdPが要求を理解できない、あるいは受け入れられない場合は、エラーのStatusとともに後述のInvalidNameIDPolicyが返ります。

AllowCreateの既定値はfalseです。省略したままにすると、IdPがそのユーザーに識別子をまだ発行していない場合はAssertionを返せず、認証が通りません。persistentを初めて使うときにここで止まります。新規発行を認めるならtrueを明示します。

Formatを省略するかunspecifiedを指定した場合、IdPはどの種類の識別子を返してもよいことになります。狙った形式で受け取りたいなら明示します。逆にurn:oasis:names:tc:SAML:2.0:nameid-format:encryptedを指定すると、識別子は<EncryptedID>として返り、平文の<NameID>は入りません。これはNameIDPolicy専用に定義された値で、8.3節の8種類には入っていません。

IdPが対応している形式は、メタデータのNameIDFormat要素で宣言されています。連携前にここを見ておけば、SP側で選べる形式が確認できます。

IdPが受け付けるFormatは仕様より狭い

仕様が8種類を定義していても、IdPが実際に受け付けるのはその一部です。Microsoft Entra IDはAuthnRequestのNameIDPolicyについて、persistent・emailAddress・unspecified・transientの4つだけを認め、それ以外の値を指定するとエラーを返します。

返す値にも癖があります。unspecifiedを指定するとEntra IDは「形式を自分で選んでよい」と解釈し、SPごとに異なる仮名(pairwise identifier)を発行します。メールアドレスは返りません。メールアドレスで受け取る前提のSPがunspecifiedのままつながらないのは、これが原因です。AllowCreateはEntra IDでは無視されます。SPNameQualifierを指定した場合は、同じ値が応答に入ります。

切り分けの順番は、SP側の設定を疑う前に「IdPがそのFormatを受け付けるか」と「受け付けたうえで何を返すか」の2つに分けて確認することになります。IdPの公式ドキュメントで対応表を確認してから、SP側の期待値と突き合わせます。

Binding方式:HTTP-POSTとHTTP-Redirectの違い

SAMLのメッセージをどの通信方式で運ぶかを定めたものがBindingです。Bindings仕様は6種類を定義していますが、ブラウザ経由のSSOで実際に設定するのはHTTP-POSTとHTTP-Redirectの2つです。

仕様が定めるBindingは6種類

BindingURN運び方と主な用途
SOAPurn:oasis:names:tc:SAML:2.0:bindings:SOAPSOAP over HTTPでSPとIdPが直接やり取りする。Artifactの引き換えや属性の問い合わせ
Reverse SOAP (PAOS)urn:oasis:names:tc:SAML:2.0:bindings:PAOSブラウザ以外のクライアントが仲介する。後述のECP Profileで使う
HTTP-Redirecturn:oasis:names:tc:SAML:2.0:bindings:HTTP-RedirectGETのクエリパラメータで運ぶ。AuthnRequestの送信
HTTP-POSTurn:oasis:names:tc:SAML:2.0:bindings:HTTP-POSTformのhidden fieldに入れてPOSTする。Responseの送信
HTTP-Artifacturn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact本体ではなく引換券(artifact)だけをブラウザ経由で渡し、本体はSOAPで直接取りに行く
URIurn:oasis:names:tc:SAML:2.0:bindings:URIURIを指定してAssertionを1件取得する

Web Browser SSO ProfileはAuthnRequestにHTTP-Redirect・HTTP-POST・HTTP-Artifactのいずれかを認め、Responseには HTTP-POSTかHTTP-Artifactのみ を認めています。ResponseにHTTP-Redirectを使うことは仕様が明確に禁じていて、理由はResponseがブラウザの許すURL長をたいてい超えるからです。

観点HTTP-POSTHTTP-Redirect
運び方formのhidden fieldに入れてPOSTURLのクエリパラメータに載せてGET
エンコードbase64DEFLATE圧縮 → base64 → URLエンコード
サイズの制約仕様上の上限はないブラウザとサーバーのURL長の制限を受ける
署名XML署名をメッセージ内に含めるクエリパラメータ SigAlg と Signature で付ける
主な用途Response(Assertionの送信)AuthnRequest

HTTP-POST Binding(Responseの標準的な転送方式)

SPのACS(Assertion Consumer Service)URLへ、POSTリクエストでAssertionを送信します。

<form method="post" action="https://sp.example.com/acs">
  <input type="hidden" name="SAMLResponse"
    value="PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDOYWY6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24i..."/>
  <input type="hidden" name="RelayState" value="https://example.com/page"/>
  <input type="submit" value="Continue"/>
</form>

Assertionはbase64にしてPOST本文で送るため、URL長の制限を受けません。属性が多くても、証明書を含んでいても運べます。Responseの転送にこの方式を使うのはそのためです。通信内容はTLSで保護し、Assertion自体の真正性はXML署名で担保します。

hidden fieldの名前は、応答ならSAMLResponse、要求ならSAMLRequestと決まっています。送出するHTMLはXHTMLに準拠させます。

RelayStateには仕様上の長さ制限があります。80バイトを超えてはいけないので、長い遷移先URLをそのまま入れると収まりません。鍵だけを載せてURL本体はサーバー側で保持するのが実装の定石です。値はブラウザを経由する途中で書き換えられるため、チェックサムや推測できない値を使って改ざんを検知できるようにしておきます。

HTTP-Redirect Binding

IdPのSSOエンドポイントへ、GETリクエストでAuthnRequestを送信します。

https://idp.example.com/sso?SAMLRequest=jVDPb%2BMEcwx4jFKr%2Fn5YxIwOAAA&RelayState=somevalue
  &SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256
  &Signature=NyZ3S8T1U2V3W4X5Y6Z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5S6T7U8%3D

メッセージはDEFLATEで圧縮してからbase64とURLエンコードを施し、SAMLRequestまたはSAMLResponseというクエリパラメータに載せます。圧縮するのはURLに収めるためで、それでも上限はブラウザやサーバーのURL長の制限に縛られます。仕様はこの上限を数値で定めていないので、長くなりそうならHTTP-POSTに切り替えます。

この方式ではXML署名を使いません。プロトコルメッセージ自体に付いていた<ds:Signature>要素を取り除いてから圧縮し、代わりにSigAlgとSignatureのクエリパラメータで署名します。署名の対象は、URLエンコード済みのパラメータをこの順番で連結した文字列です。

SAMLRequest=value&RelayState=value&SigAlg=value
SAMLResponse=value&RelayState=value&SigAlg=value

RelayStateが無いときは、RelayState=をパラメータごと署名の対象から外します。空の値で入れてはいけません。固定の書式だと思って常に入れると、受け取る側が組み立てるバイト列と合わず、署名が通りません。

URL上の並び順は仕様が決めていないので、検証する側がこの順番に並べ替えてから計算します。URLエンコードの仕方も一通りではないため、検証にはクエリで受け取った文字列をそのまま使い、値を取り出してから再エンコードしません。クエリに他のパラメータが付いていても、署名の対象には入りません。HTTP-Redirectで署名検証が落ちる原因の多くはこのあたりです。

署名済みのAssertionのような内容を含むメッセージは、この方式で運ばないことになっています。圧縮してもURLに収まらないからです。HTTP-RedirectはAuthnRequestの送信に使い、値がアドレスバーとアクセスログに残る前提で扱います。

XML署名とXML暗号化の実装仕様

XML署名(W3C xmldsig)

AssertionおよびResponseに対して、デジタル署名を施すことで、改ざん検知と発信者認証を実現します。

<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="#_d71a3a8e9ee6e4fd0b3b1f9c0e8e5c7b">
      <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#"/>
      </ds:Transforms>
      <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
      <ds:DigestValue>jFDPb/...=</ds:DigestValue>
    </ds:Reference>
  </ds:SignedInfo>

  <ds:SignatureValue>
    5Xda3xD3M7EzM9pL2Q4R9S8T1U2V3W4X5Y6Z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5S6T7U8=
  </ds:SignatureValue>

  <ds:KeyInfo>
    <ds:X509Data>
      <ds:X509Certificate>
        MIIDXTCCAkWgAwIBAgIJAKHHCgVDRV2dMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAlB...
      </ds:X509Certificate>
    </ds:X509Data>
  </ds:KeyInfo>
</ds:Signature>

署名検証フロー(SPでの処理):

  1. AssertionのIssuerを確認
  2. IdPのメタデータからIdPの公開鍵を取得
  3. SignatureValueを公開鍵で検証
  4. DigestValueがAssertion内容と一致することを確認
  5. 署名が有効な場合のみ、Assertionを受け入れ

XML暗号化

機密属性情報(パスワード、マイナンバーなど)が含まれる場合、XML暗号化によってAssertionを保護します。

<saml:Assertion>
  <!-- 平文の要素 -->
  <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
    Type="http://www.w3.org/2001/04/xmlenc#Element">
    <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <xenc:EncryptedKey>
        <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
        <ds:KeyInfo>
          <ds:X509Data>
            <ds:X509Certificate>
              <!-- SP公開鍵 -->
            </ds:X509Certificate>
          </ds:X509Data>
        </ds:KeyInfo>
        <xenc:CipherData>
          <!-- 暗号化されたセッション鍵 -->
        </xenc:CipherData>
      </xenc:EncryptedKey>
    </ds:KeyInfo>
    <xenc:CipherData>
      <!-- 暗号化されたAttribute -->
    </xenc:CipherData>
  </xenc:EncryptedData>
</saml:Assertion>

SAML Responseの検証とステータスコード

連携がうまくいかないとき、最初に見るのはResponse内のStatusCodeです。Success以外の値は、SPとIdPのどちらを調べればよいかを教えてくれます。トップレベルのStatusCodeは4種類しかありません。

Value意味
urn:oasis:names:tc:SAML:2.0:status:Success要求は正常に処理された
urn:oasis:names:tc:SAML:2.0:status:Requester要求した側(SP)に原因がある
urn:oasis:names:tc:SAML:2.0:status:Responder応答する側(IdP)で処理できなかった
urn:oasis:names:tc:SAML:2.0:status:VersionMismatchSAMLのバージョンが合わない

Requesterが返ったらAuthnRequestの内容とSP側の設定を、ResponderならIdPの認証処理と設定を疑います。原因をもう一段細かく伝える場合は、2階層目のStatusCodeが入れ子で付きます。AuthnFailedならIdPはユーザーを認証できず、InvalidNameIDPolicyなら要求されたNameID Formatに応えられず、RequestDeniedなら要求自体を拒否したという意味になります。IdPは運用上の配慮から詳細を省くこともあるため、2階層目が無いケースもあります。

StatusCodeがSuccessなのにログインできない場合は、SP側の検証のどこで落ちているかを次の順で確認します。大半の失敗はこの5点のどれかに当たります。

  1. 署名が検証できているか(前述の検証フロー)
  2. NotBeforeとNotOnOrAfterの有効期間内か
  3. AudienceRestrictionに自分のエンティティIDが入っているか
  4. InResponseToが送信したAuthnRequestのIDと一致しているか
  5. NameIDのFormatと値がSP側の設定と合っているか

Profile:使用パターン定義

Web Browser SSO Profile

最も一般的なSAML利用シーン:ブラウザでログインが必要な場合

User Agent (Browser)
   ↓
1. ユーザーがSPのログインページにアクセス
   ↓
2. SPがAuthnRequestを生成、ブラウザを経由してIdPへ送信
   ↓
3. ユーザーがIdPで認証(パスワード、MFA等)
   ↓
4. IdPがSAML ResponseをACSにPOST
   ↓
5. ブラウザがFormをAutoSubmit
   ↓
6. SPがResponseを検証、セッション発行
   ↓
7. ユーザーが保護されたリソースにアクセス可能

Enhanced Client or Proxy Profile

OutlookなどのリッチクライアントでのSSO実装

メタデータ交換

IdPメタデータ

IdPが公開する、SPが信頼するための情報源

<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
  entityID="https://idp.example.com">

  <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">

    <KeyDescriptor use="signing">
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
          <X509Certificate>
            MIIDXTCCAkWgAwIBAgIJAKHHCgVDRV2dMA0GCSqGSIb3...
          </X509Certificate>
        </X509Data>
      </KeyInfo>
    </KeyDescriptor>

    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
      Location="https://idp.example.com/sso"/>

    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
      Location="https://idp.example.com/sso"/>

    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>

  </IDPSSODescriptor>
</EntityDescriptor>

SPメタデータ

SPが公開する、IdPが信頼するための情報源

<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
  entityID="https://sp.example.com">

  <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">

    <KeyDescriptor use="encryption">
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
          <X509Certificate>
            MIIDXTCCAkWgAwIBAgIJAKHHCgVDRV2dMA0GCSqGSIb3...
          </X509Certificate>
        </X509Data>
      </KeyInfo>
    </KeyDescriptor>

    <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
      Location="https://sp.example.com/acs" isDefault="true" index="0"/>

    <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
      Location="https://sp.example.com/acs-redirect" index="1"/>

  </SPSSODescriptor>
</EntityDescriptor>

LOCKED MSO でのSAML設定項目

LOCKED MSO はSAML認証に対応しており、SAMLに対応したクラウドサービスとSSOで連携できます。設定時に決めることになる項目と、実務でよく採る値は次のとおりです。

【認証方式】
- プロトコル: SAML 2.0
- NameID Format: emailAddress(SaaS連携で一般的)
- Binding: HTTP-POST
- 署名アルゴリズム: SHA-256
- Assertionの暗号化: AES-256

【属性マッピング】
IdPが送る属性 → サービス側の項目
- mail → メールアドレス
- givenName → 名
- sn → 姓
- department → 部門

【有効期間】
- Assertionの有効期限: 5分程度
- セッションの有効期限: 業務時間に合わせる

実装上の注意点

証明書の更新管理

SAML署名用証明書は1〜3年程度の有効期限で作られることが多く、期限切れに気づかないまま当日を迎えると、SSO経由のログインが一斉に止まります。期限は監視の対象として持ちます。切り替え期間中は、新旧どちらの証明書でも署名検証が通るようにしておくと安全です。メタデータをURLで公開しておくと差し替えを伝えやすくなりますが、自動で反映されるかはSP側の実装次第です。SPが定期的にメタデータを再取得する機能を持ち、その設定が有効になっていなければ、初回にインポートした内容のまま固定され、古い証明書を使い続けることになります。切り替えの前に、そこを確認します。

時刻同期(ClockSkew)

Assertionの有効性は、IssueInstant と NotBefore / NotOnOrAfter の時刻で判定します。IdPとSPのサーバー時刻がずれていると、正しく発行されたAssertionでも期限切れや発行前と見なされて認証が失敗します。双方でNTPによる時刻同期を前提にしたうえで、許容するズレを数十秒の幅で設定しておきます。

まとめ

SAML 2.0は要素の数が多く複雑に見えますが、Assertionの中身、それを運ぶBinding、成否を伝えるStatusCodeの3つに分けて見れば、設定のどこでつまずいているかは切り分けられます。連携作業で実際に詰まるのはNameID Formatの不一致と時刻ズレ、それに証明書の期限切れで、いずれも事前に確認できる項目です。LOCKED MSO は、この複雑さを管理画面の設定項目に落とし込んだ形でSAML SSOを提供しています。


参考資料・外部リンク

関連記事

LOCKEDの詳細を見る

シングルサインオン・認証管理でお悩みなら、LOCKEDの無料デモをお試しください。

資料請求・デモ依頼はこちら →

商標について:本記事に記載されているOkta、OneLogin、Azure AD、Microsoft Entra ID等の製品名・サービス名は、各社の商標または登録商標です。

免責事項:本記事の情報は執筆時点のものであり、各製品の最新の機能・料金・仕様については、各社の公式サイトをご確認ください。本記事の内容に基づく判断・行動について、当社は一切の責任を負いかねます。

LOCKED MSO

この課題、LOCKEDで解決できます

「IDaaS導入RFPテンプレート」など、検討に役立つ資料を無料でご用意しています

LOCKEDシリーズの詳細資料を無料でダウンロード

導入事例、機能詳細、他社比較など、検討に必要な情報をまとめた資料をご用意しています

まずは資料で詳細を確認

製品資料で機能・料金・導入事例をまとめてご確認いただけます

資料をダウンロード