SAML

企業の ID プロバイダーとサービスプロバイダー間でシングルサインオンを実現する XML ベースの認証プロトコル

認証
SAML」の技術書を見る →

SAML とは

SAML (Security Assertion Markup Language) は、ID プロバイダー (IdP) とサービスプロバイダー (SP) の間で認証・認可情報を XML 形式で交換するプロトコルである。SAML 2.0 は 2005 年 3 月に OASIS 標準として承認され、後に ITU-T 勧告 X.1141 としても採択された。2026 年 8 月時点でも、社内の ID 基盤と業務用 SaaS を結ぶ企業向けの SSO では広く使われている。仕組みの要点は、SP が自前でパスワードを持たず、IdP が署名した「この人は確かに認証した」という主張 (Assertion) を受け取って信用する点にある。多要素認証の強制やアカウントの停止を IdP 側だけで完結させられるのは、この構造の帰結である。

認証フロー

SSO の開始点は 2 通りある。ユーザーが業務アプリの URL を直接開いたときに始まるのが SP 起点 (SP-Initiated) で、SP は未認証のアクセスを受けて AuthnRequest を作り、ブラウザ経由で IdP へ送る。HTTP Redirect バインディングではこの要求を DEFLATE で圧縮して URL のクエリに載せるため、元々開こうとしていた画面の情報は要求本体ではなく RelayState に預け、認証後にそこへ戻す。

1. ユーザーが SP (例: Slack) にアクセス
2. SP が SAML AuthnRequest を生成し、IdP にリダイレクト
3. ユーザーが IdP (例: Okta) でログイン
4. IdP が SAML Response (Assertion) を生成
5. ブラウザが SAML Response を SP に POST
6. SP が Assertion を検証し、ログイン完了

[ユーザー][SP: Slack] → リダイレクト → [IdP: Okta]
                                              ↓ ログイン
[ユーザー][SP: Slack] ← POST Assertion ← [IdP: Okta]

もう 1 つは IdP 起点 (IdP-Initiated) で、ユーザーが IdP のポータルに並んだアプリのリンクを押して始まる。この経路では SP からの AuthnRequest が存在せず、IdP が Assertion を作って SP の Assertion Consumer Service へ直接 POST する。あらかじめ IdP 側にアプリごとの遷移リンクを設定しておく必要があり、SP から見れば頼んでいない Response が届く形になるため、検証は SP 起点より慎重に行う必要がある。どちらの経路に対応するかは SaaS 側の実装で決まっており、片方しか使えない製品もある。

SAML Assertion の構造

Assertion は「誰が」「いつまで」「どこ向けに」認証されたかを入れ子の XML で表す。SP が検証しなければならない項目は、この構造の中に散らばっている。

<saml:Assertion>
  <saml:Issuer>https://idp.example.com</saml:Issuer>
  <saml:Subject>
    <saml:NameID>user@example.com</saml:NameID>
  </saml:Subject>
  <saml:Conditions NotBefore="..." NotOnOrAfter="...">
    <saml:AudienceRestriction>
      <saml:Audience>https://sp.example.com</saml:Audience>
    </saml:AudienceRestriction>
  </saml:Conditions>
  <saml:AttributeStatement>
    <saml:Attribute Name="role">
      <saml:AttributeValue>admin</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>

改ざんの防止は XML 署名で行い、SP は事前に交換した IdP のメタデータに含まれる公開鍵で署名を検証する。ただし署名が通っただけでは足りない。実装で漏れやすいのは次の 4 点である。

  • ConditionsNotBefore / NotOnOrAfter: 有効期間を外れた Assertion を拒否する。IdP と SP の時計がずれていると正当な Assertion まで弾かれるため、許容するずれは小さく取り、両者の時刻同期を前提条件として扱う。
  • AudienceRestriction: 自分宛ての Assertion かを確かめる。ここを見ないと、別の SP 向けに発行されたものをそのまま受け入れてしまう。
  • InResponseTo と再利用の拒否: SP 起点では自分が出した AuthnRequest の ID と対応しているかを照合し、一度使った Assertion の ID を記録して使い回しを断る。
  • 署名の対象: 署名は Response 全体に付く場合と Assertion に付く場合がある。「どこかに署名がある」ではなく「自分が信用しようとしているデータそのものが署名対象か」を確認する。

最後の項目は理屈上の注意ではない。XML 署名は署名対象を参照で指す仕様のため、署名済みの要素を文書内の別の場所へ移し、参照されない位置に偽の要素を差し込む XML 署名ラッピングという攻撃が成立し得る。2012 年の USENIX Security で発表された調査では、対象とした主要な SAML 実装 14 種のうち 11 種にこの種の欠陥が見つかっている。署名検証を自作せず、保守が続いているライブラリに任せるべき理由がここにある。

OIDC との比較

両者は新旧の関係というより、想定していた利用者が違う。SAML はブラウザと企業の ID 基盤を前提に設計され、OIDC はモバイルアプリや SPA を含む前提で作られている。

観点SAML 2.0OpenID Connect
データ形式XMLJSON / JWT
用途エンタープライズ SSOWeb / モバイルアプリ
実装の複雑さ高い (XML 署名、パース)低い (JSON、JWT)
モバイル対応不向き適している

新規に選べるなら、ライブラリが揃っている OIDC の方が実装は軽い。SAML を選ぶのは、社内の ID 基盤や連携先の SaaS が SAML しか話せない場合である。両方を話せる IdP を挟み、社内は SAML・自社アプリは OIDC と変換する構成もとれる。既存の SAML 連携をわざわざ置き換える利点は薄いので、新しく増える分から OIDC に寄せるのが現実的な進め方になる。

AWS での SAML 連携

  • IAM Identity Center: 外部の SAML IdP を ID ソースにして、複数の AWS アカウントとロールへのアクセスをまとめて払い出す
  • Cognito User Pool: SAML IdP をフェデレーション ID プロバイダーとして設定し、自社アプリケーションのログインに使う
  • IAM SAML プロバイダー: IdP のメタデータを登録し、AssumeRoleWithSAML で Assertion を一時的な AWS 認証情報に交換する

AssumeRoleWithSAML の呼び出しには AWS の認証情報が不要で、呼び出し元の正当性は登録済みメタデータの鍵で検証される。セッションは既定で 1 時間、DurationSeconds には 900 秒からそのロールの最大セッション時間 (1 時間から 12 時間の範囲で設定) までを指定できるが、Assertion の SessionNotOnOrAfter が先に来る場合はそちらで打ち切られる。なお IAM Identity Center が管理するロール (名前が AWSReservedSSO_ で始まるもの) に対してこの API は使えないため、Identity Center 経由の SSO と自前の SAML 連携は別の道具として設計する。

SAML 連携で実際に詰まる場所は毎回よく似ている。IdP の署名証明書の期限切れ、IdP と SP の時刻ずれ、そして Assertion の宛先違いである。証明書には有効期限があり、更新手順と期限の監視を連携を組んだ時点で決めておかないと、ある朝いきなり全員がログインできなくなる。

この記事は役に立ちましたか?

関連用語

関連する記事