- IAM 入門
- SAML 2.0とは?
SAML 2.0とは?
Security Assertion Markup Language(SAML)2.0は、異なるセキュリティドメイン間でのアイデンティティフェデレーションを実現し、シングルサインオン(SSO)を提供するためのXMLベースのプロトコルです。SAMLを利用すると、ユーザーは一度だけアイデンティティプロバイダー(IdP)で認証を行えば、その後は認証情報を再入力することなく、複数のサービスプロバイダー(SP)にアクセスできます。
SAML 2.0は2005年にOASISのオープン標準として承認されました。現在でも企業や政府機関のアイデンティティフェデレーションで広く利用されていますが、近年ではモダンなアプリケーションではOpenID Connect(OIDC)の採用が増えています。
例:社員が社内ポータルにログインした場合を考えてみましょう。SAMLを利用すると一日中GitHub EnterpriseのリポジトリやJiraのチケット、Confluenceのドキュメントにすぐにアクセスでき、それぞれのツールを利用するたびに認証情報を再入力する必要がありません。この場合、社内ポータルはSPとして機能するか、あるいはIdPがホストするアプリケーションランチャーとして機能し、ダウンストリームのツール(JiraやGitHub Enterpriseなど)は、同じIdPを信頼する別のSPとして動作します。
SAML認証フロー
SAMLでは2つの開始パターンがサポートされており、どちらのパターンでもSSOが実現されます。
SP-Initiatedフロー(B2B SaaSで一般的)
ユーザーがアプリケーションに直接アクセスしようとした場合のフローです。
- ユーザーがアプリケーション(SP)へのアクセスを試みる
- アプリケーションがユーザーをIdPのログインページへリダイレクトする
- ユーザーがIdPで認証を行う
- IdPが署名付きのSAMLアサーションを生成する
- IdPがアサーションを付与した状態で、ユーザーを元のアプリケーションへリダイレクトする
- アプリケーションがアサーションの署名を検証し、セッションを作成する
- ユーザーがアプリケーションを利用できるようになる
IdP-initiatedフロー(エンタープライズ環境で一般的)
ユーザーが企業のダッシュボードから利用を開始する場合のフローです。
- ユーザーが企業ポータル(IdP)にログインする
- ユーザーがダッシュボード上のアプリケーションをクリックする
- IdPが署名付きのSAMLアサーションを生成する
- IdPがアサーションを付与した状態で、ユーザーを自動的にアプリケーション(SP)へリダイレクトする
- アプリケーションがアサーションを検証し、セッションを作成する
- ユーザーがアプリケーションを利用できるようになる
どちらのフローでも、システム間でパスワードを共有することなくユーザーのアイデンティティを確認できます。また、IdPはアサーションを発行する前に多要素認証(MFA)を要求できるため、セキュリティをさらに強化できます。
IdP-Initiated SSOでは、SPからのInResponseTo値は含まれません。そのためSPはIdP-Initiatedのアサーションを検証する際、アサーションのタイムスタンプ(NotBefore/NotOnOrAfter)やリプレイ攻撃防止の仕組みに、より大きく依存することになります。
SAMLの仕組み:基本的な概念
SAMLは、主に次の3つの構成要素によってアイデンティティフェデレーションを実現します。
- IdP:ユーザーを認証し、認証情報を保管するシステム
- SP:認証をIdPに委ねて、その後アクセスを許可するアプリケーション
- SAMLアサーション:電子署名されたXMLドキュメントで、検証済みのユーザー情報を含み、IdPからSPへ受け渡される
SAMLアサーションは、ユーザーのアイデンティティ確認が完了していることと、そのユーザーに許可されたアクセス権限を証明します。これにより、SPはユーザーの認証情報を直接扱うことなく、そのユーザーに対してアクセスを許可するか拒否するかを判断できます。
SAMLアサーションの構造
SAMLアサーションは、構造化されたXMLドキュメントであり、3種類のステートメントで構成されます。
- 認証ステートメント:ユーザーが認証済みであることを示し、その認証イベントの日時を記録する。
- 属性ステートメント:ユーザーデータやクレーム(Eメールアドレス、氏名、グループ、ロール)を含む。ほとんどの導入環境では、認可情報(ロールやグループなど)は属性ステートメントを通じて伝達される。従業員向けのSAML導入環境では、属性ステートメントにグループやロールなどの認可関連データが含まれるのが一般的。
- 認可の判断ステートメント:SAML仕様で定義されているが、現在のSSO実装ではほとんど使用されていない。
アサーションには、次の情報が含まれます。
- Issuer(発行者):どのIdPがアサーションを作成したかを示す
- Subject(サブジェクト):ユーザーが誰であるかを示す
- Conditions(条件):有効期間(
NotBeforeやNotOnOrAfterなど)と想定される対象者を示す - Signature(署名):真正性を証明するための暗号学的な署名。XML署名ラッピング攻撃を防ぐため、SPは処理対象の要素が、署名内の参照IDによって指定されている要素と同一であることを検証する必要がある
アサーションは暗号化される場合があります。通常は<Response>全体ではなく<Assertion>要素が暗号化されますが、機密性の高いデータについては個々の属性が暗号化されることもあります。SPは、暗号化された要素を必要に応じて復号できる必要があります。
SAML、OAuth 2.0、OpenID Connectの比較
開発者はSAML、OAuth 2.0、OIDCを混同しがちです。これらの違いを以下に示します。
| 項目 | SAML 2.0 | OAuth 2.0 | OpenID 接続 |
|---|---|---|---|
| 主な用途 | エンタープライズSSO認証 | 委任された認可 | 最新の認証 |
| 形式 | XML(解析が複雑で、XML署名ラッピング攻撃のリスクがある) | 仕様上はトークン形式を規定していないが、多くの実装ではJWTアクセストークンが使用される | JSONベース(JWT IDトークン) |
| トークンの種類 | SAMLアサーション | アクセストークン | IDトークンとアクセストークン |
| 通信方式 | 認証リクエストには通常HTTP-Redirectが使用され、アサーションはほぼ常にHTTP-POSTで送信される | 通常はHTTP Authorizationヘッダー(Bearerトークン)を使用。ただし、フローによっては他の方式(form_postやqueryなど)も利用される | HTTP Authorizationヘッダー |
| モバイル対応 | ネイティブアプリのサポートは限定的(WebViewやブローカーアプリが必要になることが多い) | 非常に優れている | 非常に優れている |
| ターゲット オーディエンス | 企業、政府機関 | 消費者アプリ、API | 消費者アプリ、モダンなエンタープライズ環境 |
| ユースケース | エンタープライズSSO、従業員認証 | APIアクセス権限の委任、サードパーティ統合 | モダンアプリ、モバイル認証、消費者向けSSO |
OAuth 2.0は、認証(ユーザーが誰であるか)ではなく、認可(何を実行できるか)を扱います。OAuth 2.0単体は認証プロトコルではありません。プロバイダーによっては、独自の方法でアイデンティティ情報をOAuth 2.0に追加している場合がよくありますが、それらの方法は標準化されていません。OAuth 2.0に認証機能を追加するための標準規格がOpenID Connectです。
SAMLは認証を扱います。認可に関する属性情報を含めることもできますが、SAML自体は認可フレームワークではありません。認可の判断は、SAMLによる認証が完了した後にアプリケーション側で行われます。
これらのプロトコルは相互排他的なものではありません。多くのアイデンティティプラットフォームは、3種類のすべてをサポートしており、ユーザーのニーズに応じて適切なものを選択できます。
SAML統合における一般的な課題
XML署名の検証
SAMLはセキュリティのためにXML署名を利用しています。しかし、検証を正しく実装するのは容易ではありません。
- 署名アルゴリズムを検証する(SHA-1のような脆弱なアルゴリズムは拒否する)
- 署名証明書チェーンを検証する
- 証明書の有効期限と失効状態を確認する
- 署名された要素と解析対象のコンテンツが一致していることを確認する
- SPは、構成に応じて
<Response>または<Assertion>のいずれかに付与された、信頼できる署名を少なくとも1つ検証し、想定された要素のみが処理されることを確認する必要がある - SPは、XMLラッピング攻撃を防ぐため、署名が正しい参照先を対象としていることを確認しなければならない。一部のライブラリでは参照先の検証が強制されない場合があるため、署名が正しい要素IDを参照していることを検証する必要がある
署名検証でわずかでも誤りがあると、セキュリティ上の脆弱性が生じます。攻撃者はXML署名ラッピング攻撃を悪用して認証を回避できる可能性があります。
独自に実装するのではなく、テスト済みのSAMLライブラリを利用することを検討してください。
クロックスキューとタイムスタンプの検証
SAMLアサーションには、(NotBefore)と(NotOnOrAfter)の条件が含まれています。IdPとSPの時計にずれがあると、有効なアサーションが拒否される可能性があります。
ベストプラクティス
- 2~5分程度のクロックスキュー許容範囲を設ける
- サーバーで適切なNTP設定を行う
- デバッグしやすいように、タイムスタンプ検証の失敗を個別にログへ記録する
メタデータの交換
SAMLでは、仕様上必須ではないものの、通常はIdPとSPの間でメタデータを交換します。
- IdPメタデータ:署名証明書、エンドポイント、エンティティIDを含む
- SPメタデータ:アプリケーションのACS(Assertion Consumer Service)URLや要件を記述する
メタデータが変更されると、SSOが機能しなくなります。IdPが証明書を更新した場合は、設定も更新する必要があります。また、一部の企業ではSPメタデータの変更に手動承認が必要なため、導入作業が遅れることがあります。
IdPメタデータは設定ファイルではなくデータベースに保存してください。なお、すべてのIdPが動的メタデータURLをサポートしているわけではありません。利用可能な場合は、自動更新がベストプラクティスです。
属性マッピングの不整合
IdPによって送信される属性名は異なります。そのため、アプリケーション側では、こうした違いに対応できるよう柔軟な属性マッピングが必要となります。顧客がSAML属性とアプリケーションのユーザーフィールドとの対応付けを設定できるようにしておくとよいでしょう。
ロールベースアクセス制御(RBAC)を使用している場合、IdPはSAML属性を通じてロール情報を送信できます。その場合、アプリケーションはIdPから受け取ったロールを内部の権限管理システムにマッピングする必要があります。
SAMLのセキュリティに関するベストプラクティス
署名を必ず検証する
すべてのSAMLアサーションについて、暗号学的な署名検証を実施して以下の点を確認する必要があります。
- 署名が存在すること
- 署名がアサーションの内容に対して有効であること
- 署名証明書が信頼されたルート証明書まで連なること
- 署名された要素と解析対象のコンテンツが一致していること。SPは、XMLラッピング攻撃を防ぐため、署名が正しい参照先を対象としていることを確認しなければならない。
開発環境であっても、署名検証を省略してはいけません。署名検証はSAMLセキュリティの基盤となるものです。
アサーションのすべての条件を検証する
署名の検証に加えて、次の項目も検証する必要があります。
- Issuer(発行者):設定されているIdPと一致していること
- Audience(対象者):アプリケーションのエンティティIDが含まれていること
- NotBefore/NotOnOrAfter:現在時刻が有効期間内であること
- Recipient(受信者):ACS(Assertion Consumer Service)URLと一致していること(存在する場合)
- InResponseTo:認証リクエストIDと一致していること(SP-Initiatedフローの場合)
リプレイ攻撃と署名ラッピング攻撃を防止する
SAML仕様では、アサーションの使用を1回限りと義務付けていません。そのため、リプレイ攻撃への対策はSP側の責任となります。
- リプレイ防止のため、Assertion ID(Response IDではなく)をnonceのように利用し、アサーションの有効期間に対応したTTL付きキャッシュに保存する
ベストプラクティス:キャッシュのTTLは少なくともアサーションのNotOnOrAfterで定められた有効期間と同じ長さにし、さらにネットワーク遅延を考慮して数秒程度の余裕を持たせる - 以前に受け取ったことのあるIDを持つアサーションはすべて拒否する
- キャッシュサイズを適切に管理するため、期限切れのIDを定期的に削除する
第一の防御策として、SPはNotBeforeとNotOnOrAfterのタイムスタンプを検証する必要があります。Assertion IDのキャッシュによる対策は、二次的な防御策です。
すべての通信でHTTPSを使用する
SAMLアサーションはHTTPS経由でのみ送信する必要があります。アサーションには署名が付与されていますが、HTTP経由で送信するとユーザーを中間者攻撃のリスクにさらすことになります。
ACS(Assertion Consumer Service)URLはHTTPSのみを使用するよう設定してください。ほとんどのIdPは、HTTPエンドポイントに対して警告を表示するか、接続を拒否します。
ログアウトを適切に実装する
SAMLはシングルログアウト(SLO)をサポートしており、ユーザーは接続されたアプリケーションのすべてから一度にサインアウトできます。実装は必須ではありませんが、セキュリティ要件の高いアプリケーションでは推奨されます。
SLOは、ブラウザのリダイレクトを利用するフロントチャネル方式と、サーバー間通信を利用するバックチャネル方式のいずれかで実装できます。フロントチャネル方式のSLOは広くサポートされていますが、動作が不安定になりやすい面があります。一方、バックチャネルログアウトも存在しますが、実装が複雑であり、実際にはほとんど採用されていません。また、IdPやSPによってSLOの実装方法が異なるため、相互運用性にはばらつきがあります。複数のプロバイダーとの接続を想定してテストを行うようおすすめします。
SAMLの実装オプション
SAMLをゼロから安全に実装するには、XMLセキュリティに関する高度な専門知識が必要です。そのため一般的には、IdPの実装や高度に専門的なユースケースに限って推奨されます。
以下の選択肢を検討してください。
アイデンティティプラットフォーム
一部のアイデンティティプラットフォームは、次のような機能を提供しているため、SAML実装の複雑さに対処するのに役立ちます。
- あらかじめ構築されたSAML IdPとSPの実装
- メタデータの自動管理
- 証明書ローテーションの処理
- 1つのアプリケーションに対する複数IdPのサポート
- 詳細な監査ログ
このアプローチでは、企業顧客にはSAMLを提供しながら、消費者向けアプリケーションではモダンなプロトコル(OIDCやOAuth 2.0)を利用できます。また、一部のプラットフォームでは、異なるプロトコル間の変換がシームレスに行われます。
SAMLライブラリ
より細かな制御が必要なチーム向けには、実績のあるSAMLライブラリがXML解析、署名検証、プロトコルの低レベルな処理を担います。
- Node.js:
passport-saml、samlify - Python:
python3-saml、pysaml2 - Java:
Spring Security SAML、OpenSAML - .NET:
Sustainsys.Saml2、ITfoxtec.Identity.Saml2 - Ruby:
ruby-saml - PHP:
SimpleSAMLphp
実績のあるSAMLライブラリであっても、リプレイ攻撃への対策や暗号化されたアサーションへの対応を自動的に行ってくれるわけではありません。必要に応じて、開発者がキャッシュやnonceと復号処理を実装し、さらに署名の参照先が検証されていることを確認する必要があります。
OIDCやOAuth 2.0ではなくSAMLを選ぶべき場合
次のような場合はSAMLを選択します。
- 顧客が既存のSAML基盤を利用している企業である
- エンタープライズSSOを必要とするB2B SaaSを構築している
- 政府機関のシステムと連携する
- RFPの要件としてSAMLサポートが求められている
次のような場合はOIDCまたはOAuth 2.0を選択します。
- 消費者アプリケーションを構築している
- モバイルアプリの認証が必要である
- APIの認可を実装している
- JSONベースのよりシンプルなプロトコルを利用したい
- レガシーな要件がなく、新規にシステムを構築する
多くのアプリケーションは複数のプロトコルをサポートしています。そのため、IdPを選定する際には、エンタープライズ顧客向けのSAMLと、それ以外のユーザー向けのOIDCの両方をサポートしていることが望ましいでしょう。また、ユーザーエクスペリエンスを向上させるために、WebAuthnやパスキーなどのパスワードレス認証方式の導入も検討してください。
SAML統合テストのベストプラクティス
SAMLサポートをリリースする前に、十分なテストを実施しましょう。
複数のIdPでテストする
IdPごとにSAMLの実装には多少の違いがあります。あるIdPの挙動が、他のIdPにも当てはまるとは限りません。属性名、メタデータの形式、証明書の取り扱いはIdPによって異なります。
エッジケースをテストする
- クロックスキュー(サーバー時刻を±5分ずらしてテストする)
- 証明書のローテーション(IdPの証明書を更新し、サービス停止が発生しないことを確認する)
- 無効な署名(アサーションを改ざんし、拒否されることを確認する)
- 期限切れのアサーション(古いテスト用アサーションを使用する)
- リプレイ攻撃(有効なアサーションを再送信し、拒否されることを確認する)
検証エラーを監視する
デバッグに備えて、Assertion ID、エラーの理由、IdPのエンティティ、タイムスタンプとともに、すべてのSAML検証エラーをログに記録してください。これらのログは、顧客環境で発生した問題を調査する際に不可欠です。SAMLに関する問題は、コードの不具合よりも設定ミスが原因で発生することが少なくありません。
SAMLに関するよくある質問
SAMLはどのような問題を解決しますか?
SAMLは、企業ユーザー向けのアイデンティティフェデレーションを可能にすることで、SSOを提供します。SAMLの主な利点は、ユーザーパスワードの保管や管理の責任を専用のIdPに委ねることで、アプリケーションのセキュリティを簡素化できる点にあります。その結果、アプリケーションの攻撃対象領域を縮小できるほか、パスワードリセットに関するヘルプデスクへの問い合わせを減らし、セキュリティポリシーの適用を一元化できます。
SAMLは認証ですか、それとも認可ですか?
SAMLは主に認証とフェデレーションのためのプロトコルであり、ユーザーのアイデンティティを確認することを目的としています。それ自体はOAuth 2.0のような認可フレームワークではありません。SAMLは、IdPからSPへ署名付きアサーション(ユーザーの身元を示す情報)を送信することで、「このユーザーは誰か?」という問いに答えます。一方、認可(ユーザーに何が許可されているかの判断)は、SAML認証が完了した後に行われます。その際には通常、SAMLアサーションに含まれるユーザー属性(ロールや所属部門など)が利用されます。
SAMLはOAuth 2.0やOpenID Connectとどのように異なるのですか?
SAMLは、企業向けのアイデンティティフェデレーションや従業員向けのSSOを目的として設計された、XMLベースの比較的古い標準規格です。OAuth 2.0は認可フレームワークであり、APIに対する限定的なアクセス権限を委任するためのアクセストークンを発行します。OIDCはOAuth 2.0の上に構築されたアイデンティティレイヤーであり、IDトークン(JWT)を用いた標準化された認証機能を提供します。Webアプリケーション、モバイルアプリケーション、API中心のアプリケーション向けに最適化されています。これら3つはいずれもアクセスを実現しますが、SAMLがエンタープライズSSOに重点を置いているのに対し、OAuth 2.0とOIDCはモダンアプリケーションにおける認証やAPI認可により適しています。
SAMLは現在でも利用されていますか?
はい。SAMLは現在でもエンタープライズSSOの主要なプロトコルであり、特に既存のアイデンティティインフラストラクチャを持つ大規模組織や政府機関で広く利用されています。アプリケーション向けにはOIDCの採用が進んでいますが、SAMLは企業環境で広く普及しているため、引き続き積極的に利用・サポートされています。
SAMLは安全ですか?どのようなセキュリティリスクがありますか?
SAMLは、適切に実装されていれば安全です。SAMLは、XMLデジタル署名や暗号化を利用してアイデンティティ情報を保護します。一方で、アサーションの検証が適切に行われない場合には、リスクが生じる可能性があります。SPは、XML署名の検証、発行者(issuer)・対象者(audience)・タイムスタンプなどのアサーション条件の検証、リプレイ攻撃対策を実施する必要があります。
アイデンティティソリューションの構築
Auth0を利用すると、SAML基盤をゼロから構築・運用することなく、エンタープライズSSOを迅速かつ安全に実装できます。
アイデンティティとアクセス管理に関しては、「IAM入門」シリーズをご覧ください。
これらの資料は一般的な情報提供のみを目的としています。本資料の利用者は、自身の責任において、自身の専門アドバイザーからセキュリティ、プライバシー、コンプライアンス、またはビジネスに関する助言を得るものとし、本資料に記載された情報のみに依存すべきではありません。
Quick assessment
SAML のメリットとは次のどれですか?
Quick assessment
シングルサインオン(SSO)がユーザーにとってメリットがある理由は何ですか?
Quick assessment
アイデンティティプロバイダー(IdP)は、SAML 2 では、どのような役割を担っていますか?