OpenID Connect の記事の最後で、次は SAML・OAuth・OpenID Connect の違いを整理すると書きました。Entra ID でエンタープライズアプリのシングルサインオンを設定しようとすると、方式の選択肢に SAML と OpenID Connect が並んでいます。この記事では、3つが何に答えるしくみなのかを並べたうえで、このシリーズでまだ扱っていなかった SAML のしくみを、仕様と Microsoft(Entra ID)のドキュメントで確かめながら、最初の準備から一歩ずつ図にしました。
- OAuth 2.0 は認可、OpenID Connect と SAML は認証(サインイン)のしくみ
- SAML と OpenID Connect で、片方でしかできない(難しい)こと
- SAML の登場人物(IdP・SP)と、アサーションに入っているもの
- SAML でシングルサインオンするときの流れと、アプリが確かめること
- Entra ID で SAML のシングルサインオンを設定するときに交換する値
- 新しいアプリは OpenID Connect、SAML はアプリや相手が求めるときに選ぶ
まずはたとえで:紹介状・名札・部屋の鍵
会社の受付で身分証を見せると、受付が3種類のものを出してくれるとします。1つ目は、取引先の会社あてに「この人は営業部の田中さんで、何時に本人確認をしました」と書いて封をし、印を押した紹介状です。2つ目は、社内の会議に出るための名札です。3つ目は、決まった部屋に入るための鍵です。
SAML のアサーションは紹介状、OpenID Connect の ID トークンは名札、OAuth 2.0 のアクセストークンは部屋の鍵にあたります。紹介状と名札は「この人は誰か」を相手に伝えるもので、鍵は「どこに入ってよいか」を渡すものです。紹介状と名札は、伝える中身はよく似ていますが、書き方が違います。SAML は XML で書き、OpenID Connect は JSON(JWT)で書きます。
3つの違い
答える問いが違う
OAuth 2.0(RFC 6749)は、アプリが API を使うための権限を、利用者に代わって受け取るしくみです(OAuth 2.0 の記事)。答えるのは「このアプリに何をさせてよいか」で、これを認可と呼びます。OpenID Connect と SAML が答えるのは「誰がサインインしたか」で、これは認証です。どちらも、1回のサインインで複数のアプリを使えるようにするシングルサインオン(SSO)に使われます。
| 項目 | OAuth 2.0 | OpenID Connect | SAML 2.0 |
|---|---|---|---|
| 目的 | 認可(API を使う権限) | 認証(サインイン) | 認証(サインイン)と属性の受け渡し |
| 出すもの | アクセストークン | ID トークン(+アクセストークン) | アサーション |
| 形式 | 仕様では決めていない(Entra ID は JWT) | JWT(JSON) | XML |
| 署名 | 形式による | JWS(RS256 など) | XML 署名 |
| 設定の共有 | この RFC では決めていない | Discovery(JSON) | メタデータ(XML) |
| SPA・モバイル | 使える(PKCE を使う) | 向いている | 扱いにくい |
| 仕様 | IETF の RFC 6749(2012年) | OpenID Foundation の OIDC Core 1.0(2014年) | OASIS の SAML 2.0(2005年) |
OpenID Connect は OAuth 2.0 の上に作られた「ID の層」なので、サインインと同時にアクセストークンももらえます。SAML は OAuth 2.0 とは別に作られたしくみで、SAML のアサーションはアプリ(SP)あてのものです。SAML でサインインしたアプリが API を呼ぶには、別にアクセストークンが要ります。Microsoft は、SAML のアサーションを OAuth 2.0 のアクセストークンに引き換える流れ(SAML bearer assertion flow)も用意していますが、これは別の流れとして扱われています。
サインインの結果の届け方が違う
もう1つの大きな違いは、サインインの結果がアプリにどう届くかです。SAML でよく使う HTTP POST のやり方では、署名つきのアサーションそのものが、ブラウザを通ってアプリに届きます。OpenID Connect の認可コードフローでは、ブラウザを通るのは認可コードだけで、ID トークンはアプリのサーバが Entra ID から直接受け取ります。
ブラウザを通るものは、途中で書き換えられるおそれがあります。そのため SAML のプロファイル(使い方の決まり)は、HTTP POST で届けるアサーションには署名を必須にしています。アプリ(SP)は、署名と中身の両方を確かめてから使います。SAML には、アサーションを裏でサーバどうしで取りに行く「アーティファクト」という方式もありますが、Entra ID はこれに対応していません。
SAML と OpenID Connect、片方でしかできないこと
SAML と OpenID Connect は、どちらも「誰がサインインしたか」をアプリに伝えるしくみです。ブラウザで Web アプリにシングルサインオンするだけなら、どちらでもできます。差が出るのはその外側で、「API も呼ぶか」「どんな種類のアプリか」「つなぐ相手が何に対応しているか」の3つです。
| やりたいこと | OpenID Connect | SAML | 理由 |
|---|---|---|---|
| Web アプリへのシングルサインオン | できる | できる | どちらも「誰か」を署名つきでアプリに伝える |
| サインインと一緒に API のトークンをもらう | できる(1回の要求で ID トークンとアクセストークン) | できない。別の流れで引き換える | OIDC は OAuth 2.0 の上に作られている。SAML のアサーションはアプリ(SP)あて |
| SPA・モバイルアプリのサインイン | 向いている | 扱いにくい | SAML は、サーバの ACS URL へのブラウザの POST が前提。Microsoft も SPA・モバイルには OIDC が必要としている |
| IdP の画面(マイアプリなど)から開く | IdP がアプリに転送し、アプリが要求を出し直す | 要求なしでアサーションを送れる | SAML は要求なしの応答を決めている。OIDC はアプリに要求を出させる |
| SAML にしか対応しない SaaS や IdP とつなぐ | できない | できる | SAML だけに対応するアプリや IdP がある |
| 中身を暗号化する | 仕様ではできる(JWE) | できる。Entra ID では SAML アプリに設定できる(P1・P2) | Entra ID の管理画面のトークンの暗号化は、SAML のアプリだけが対象 |
| Entra ID でマルチテナントのアプリにする | できる | できない | Entra ID の SAML は、単一テナントかギャラリーのアプリだけ |
| Microsoft のライブラリで組み込む | MSAL・Microsoft.Identity.Web がある | ない | Microsoft は SAML の開発用ライブラリを出していない |
並べてみると、SAML にしかない機能は多くありません。SAML の強みは、企業向けの SaaS や既存の IdP で広く使われていて、相手がすでに対応していることです。逆に、API を呼ぶアプリや、SPA・モバイルアプリをこれから作るなら、OpenID Connect(と OAuth 2.0)でないと組み立てにくくなります。この使い分けは、後の「どれを選ぶか」でもう一度まとめます。
SAML の基本の形(OASIS SAML 2.0)
ここからは、標準(OASIS の SAML 2.0)で決まっている一般的な話です。SAML(Security Assertion Markup Language)は、組織どうしでセキュリティの情報をやり取りするための、XML の枠組みです。
登場人物と用語
SAML では、利用者を認証して「この人は誰か」を述べる側を IdP(アイデンティティプロバイダ)、その内容を受け取って使うアプリを SP(サービスプロバイダ)と呼びます。OpenID Connect の OP と RP にあたります。IdP と SP は、お互いを識別子(Entity ID)で見分けます。
| 用語 | 意味 |
|---|---|
| アサーション | IdP が利用者について述べた XML の文書。SAML の中心になるもの |
| AuthnRequest | SP が IdP に「この利用者を認証してほしい」と頼む要求 |
| Response | IdP の応答。成功するとアサーションが入っている |
| 識別子(Entity ID) | IdP や SP の名前。URL の形をしていることが多い |
| ACS URL | Assertion Consumer Service の URL。SP がアサーションを受け取る窓口 |
| バインディング | SAML のメッセージを HTTP にどう載せるかの決まり(HTTP Redirect、HTTP POST など) |
| メタデータ | 識別子・URL・証明書などの設定を、IdP と SP の間で共有するための XML |
| RelayState | 要求と一緒に送り、応答で戻ってくる値。サインイン後に開くページを伝えるのに使う |
アサーションの中身
アサーションには、3種類の文(ステートメント)を入れられます。いつ・どの方法で認証したかを示す認証の文、名前やメールなどを示す属性の文、そして認可の決定の文です。シングルサインオンでよく使うのは、認証の文と属性の文です。
このうち、アプリが特に気にするのが Subject と Conditions です。Subject の NameID が「誰か」を表し、SubjectConfirmation には、受け取り先の ACS URL(Recipient)、届けてよい期限(NotOnOrAfter)、どの要求への答えか(InResponseTo)が入ります。Conditions には、使ってよい時間と、どの SP あてか(Audience)が入ります。
OpenID Connect の ID トークンと並べると、名前は違っても、同じ役目のものがそろっています。
基本の流れ(SP から始める場合)
SAML の使い方の決まり(プロファイル)のうち、ブラウザでシングルサインオンするものを Web Browser SSO プロファイルと呼びます。利用者が先にアプリ(SP)を開く場合の、基本の流れは次のとおりです。
SP は AuthnRequest を作り、ブラウザを IdP へ転送します(HTTP Redirect)。IdP は利用者を確かめ、すでに IdP にサインインしていればそのまま、まだならサインインさせます。IdP はアサーションを作って署名し、自動で送信されるフォームをブラウザに返します。ブラウザがそのフォームを SP の ACS URL に POST し、SP は中身を確かめてセッションを作ります。この流れでは、SP と IdP は直接通信しません。
SP が確かめること
Web Browser SSO プロファイルは、SP が受け取ったアサーションで確かめることを決めています。
- 署名:アサーション(または応答)の署名を、IdP の証明書の公開鍵で確かめます。
- 受け取り先と期限:
Recipientが、そのアサーションを受け取った ACS URL と同じか。NotOnOrAfterを過ぎていないか。 - 要求との対応:
InResponseToが、自分が送った AuthnRequest の ID と同じか。OpenID Connect のnonceと似た役目です。 - あて先と発行者:アサーションには SP の識別子を入れた
Audienceが必ず入ります。自分あてかどうかと、信頼している IdP が出したものか(Issuer)を確かめます。
どれか1つでも合わないアサーションは捨て、セッションを作りません。アプリを作る側は、これらの確認を自分で XML を読んで書くのではなく、SAML に対応した製品やライブラリの機能に任せます。
ここからは Microsoft(Entra ID)の場合です
ここからは、Entra ID を IdP にして、業務で使う SaaS アプリ(SP)に SAML でシングルサインオンする場合を見ていきます。Entra ID では、SaaS アプリを「エンタープライズアプリ」として登録し、そこで SAML を設定します。
誰が何を持つか
Entra ID は、アサーションに署名する秘密鍵を、エンタープライズアプリごとに持ちます。OpenID Connect や OAuth 2.0 のトークンは Entra ID で共通の証明書で署名されますが、SAML の署名用の証明書はアプリごとに作られるのが違いです。SaaS アプリは、その証明書(公開鍵)だけを持ち、届いたアサーションの署名を確かめます。
準備の流れ
サインインの前に、管理者が Entra ID とアプリの両方に値を登録します。お互いの「名前(識別子)」「受け口(URL)」「確かめる鍵(証明書)」を交換する作業です。
| 手順 | 誰が・どこで | 何をするか | 鍵(物)はどうなるか・使う鍵 |
|---|---|---|---|
| ① | 管理者・Entra 管理センター | エンタープライズアプリを追加する | アプリの入れ物ができる。まだ鍵はない |
| ② | 管理者・Entra 管理センター | シングルサインオンの方式で SAML を選ぶ | ― |
| ③ | 管理者・アプリの管理画面 | SAML の設定ページを開く | ― |
| ④ | アプリ → 管理者 | SP の識別子と ACS URL を表示する | SP の名前と受け口を控える |
| ⑤ | 管理者・Entra 管理センター | 識別子・応答 URL・サインオン URL を登録する | Entra ID が SP の名前と受け口を持つ |
| ⑥ | Entra ID | 署名用の証明書を作る | 秘密鍵は Entra ID の中にだけある。既定で3年有効 |
| ⑦ | Entra ID → 管理者 | 証明書・ログイン URL・識別子をダウンロード・コピーする | 証明書は公開鍵だけ。秘密鍵は渡らない |
| ⑧ | 管理者・アプリの管理画面 | ⑦の値と証明書を登録する | アプリが Entra ID の証明書(公開鍵)を持つ |
| ⑨ | 管理者・アプリの管理画面 | 利用者のアカウントを用意する | NameID と同じ値で、アプリ側の利用者と結びつける |
| ⑩ | 管理者・Entra 管理センター | 利用者・グループを割り当てる | 割り当てた人がこのアプリを使える |
サインインの流れ
準備ができたら、利用者がアプリを開いたところから、サインインが終わるまでを見ます。Entra ID は、要求(AuthnRequest)を HTTP Redirect で受け取り、応答(Response)を HTTP POST でアプリに届けます。
| 手順 | 誰が・どこで | 何をするか | 鍵(物)はどうなるか・使う鍵 |
|---|---|---|---|
| ⑪ | 利用者・ブラウザ | サインインが要るページを開く | まだアプリのセッションはない |
| ⑫ | アプリ | AuthnRequest を作り、その ID を覚える | ID は⑳で InResponseTo と比べる |
| ⑬ | アプリ → ブラウザ | Entra ID のログイン URL へ転送する | SAMLRequest と RelayState を URL に入れる |
| ⑭ | ブラウザ → Entra ID | ログイン URL を開き、要求を届ける | 要求には⑤で登録した識別子が Issuer として入る |
| ⑮ | Entra ID | どのアプリの要求かを探す | Issuer と識別子、ACS URL と応答 URL が合うか |
| ⑯ | Entra ID | 利用者をサインインさせる | 多要素認証や割り当てを確かめる |
| ⑰ | Entra ID | アサーションを作って署名する | ⑥のアプリ用の秘密鍵で署名する |
| ⑱ | Entra ID → ブラウザ | 自動で送信されるフォームを返す | アサーション入りの SAMLResponse がブラウザに来る |
| ⑲ | ブラウザ → アプリ | 応答 URL(ACS)に POST する | アサーションはそのまま運ばれる |
| ⑳ | アプリ | アサーションを確かめる | ⑧で登録した証明書(公開鍵)で署名を確かめる |
| ㉑ | アプリ | NameID で利用者を探し、セッションを作る | Cookie を発行する |
| ㉒ | アプリ → ブラウザ | ページを返す | 以降はアプリのセッションで使う |
⑯で Entra ID にサインインしたあとは、Entra ID のセッションが残ります。ほかのアプリでも同じように⑪から始めると、⑯でサインインの画面を出さずに進めます。これがシングルサインオンです。
IdP から始める場合(マイアプリから開く)
SAML では、アプリからではなく、IdP から始めることもできます。Entra ID では、マイアプリの画面でアプリのタイルを選ぶ使い方です。このとき Entra ID は、要求なしでアサーションをアプリに送ります。
| 項目 | 最初の図(SP から始める) | この図(IdP から始める) |
|---|---|---|
| 始まり | 利用者がアプリを開く | 利用者がマイアプリでタイルを選ぶ |
| AuthnRequest | アプリが作って送る(⑫〜⑭) | ない |
| InResponseTo | 入っていて、⑫の ID と比べる | 入っていない(入れてはいけない) |
| 開くページ | RelayState で戻る | リレー状態の値か、アプリが決めた既定のページ |
| Entra ID の設定 | サインオン URL を設定する | サインオン URL を空にする |
要求がないので、アプリは「自分が頼んだ答えか」を InResponseTo では確かめられません。署名・Audience・Recipient・期限の確認がより大事になります。アプリが SP から始める流れに対応していれば、そちらを使う設定にしておくと、図12の流れになります。
設定の手順(Entra ID)
エンタープライズアプリを追加し、SAML を選ぶ(図11の①②)
Microsoft Entra 管理センターで Entra ID ›› Enterprise apps ›› All applications を開き、アプリを追加します。ギャラリーにあるアプリは名前で探し、ない場合は Create your own application から、ギャラリーにないアプリとして作ります。作業にはクラウドアプリケーション管理者などのロールが要ります。
追加したアプリの Single sign-on を開き、方式で SAML を選びます。SAML のシングルサインオンを設定できるのは、単一テナントのアプリかギャラリーのアプリだけで、マルチテナントのアプリでは選べません。ギャラリーのアプリには、アプリごとの設定ガイドが用意されているので、値はそれに従います。
SP の値を Entra ID に登録する(図11の③〜⑤)
アプリの管理画面で SAML の設定ページを開き、SP の識別子(Entity ID)と ACS URL を確かめます。その値を、Entra ID の Basic SAML Configuration(基本的な SAML 構成)に写します。
| Entra ID の項目 | 入れる値 |
|---|---|
| 識別子(Entity ID) | SP の Entity ID。AuthnRequest の Issuer と完全に一致させる。テナントの中で重複できない |
| 応答 URL(ACS URL) | SP の ACS URL。Entra ID はここにアサーションを POST する |
| サインオン URL | SP から始めるときの、アプリのサインインページ |
| リレー状態・ログアウト URL | アプリが求めるときだけ設定する |
証明書と Entra ID の値をアプリに登録する(図11の⑥〜⑧)
Entra ID は、SAML を設定したアプリに、署名用の自己署名証明書を自動で作ります。有効期間は既定で3年で、署名は既定で SHA-256 を使います。SAML Certificates の欄から、証明書(Base64 または Raw)か、フェデレーションメタデータ XML をダウンロードします。Set up(アプリ名)の欄には、ログイン URL と Microsoft Entra 識別子が表示されます。
アプリの管理画面に、ログイン URL(IdP の SSO の URL)、Microsoft Entra 識別子(IdP の Entity ID)、証明書を登録します。アプリがメタデータを URL から読み込める場合は、「アプリのフェデレーションメタデータ URL」を渡すと、証明書が変わったときにアプリ側で取り直せます(アプリが対応している場合)。この URL は次の形です。
アプリのフェデレーションメタデータ URL の形(図11の⑦)
https://login.microsoftonline.com/{tenant-id}/federationmetadata/2007-06/federationmetadata.xml?appid={appId}
証明書には期限があります。Entra ID は、期限の60日前・30日前・7日前に通知メールを送ります。通知先は既定ではアプリを追加した管理者だけで、5つまで追加できるので、担当者が替わっても届くよう配布リストを入れておくと安心です。更新するときは、新しい証明書を作って(まだ有効にしない)アプリに登録し、そのあとで Entra ID 側で有効にします。
利用者を用意して割り当てる(図11の⑨⑩)
多くのアプリでは、シングルサインオンを使う前に、アプリ側にも利用者のアカウントを作っておく必要があります。アプリは、アサーションの NameID を見て、どのアカウントでサインインさせるかを決めます。NameID に何を入れるか(ユーザー名、メールアドレスなど)は、Entra ID の「属性とクレーム」で、アプリが求める形に合わせます。
Entra ID 側では、アプリの Users and groups で、使う人やグループを割り当てます。アプリのプロパティで「割り当てが必要」を「はい」にしていると、割り当てのない人はサインインできません。グローバル管理者はこの確認の対象外なので、テストは実際に使う人のアカウントで行います。
テストして、要求と応答の中身を見る(図12の⑫〜⑳)
SAML の設定画面の「シングルサインオンのテスト」から、サインインを試せます。ここでは、Microsoft のドキュメントにある例で、要求と応答の中身を見ておきます。まず、アプリが送る AuthnRequest です。
AuthnRequest の例(図12の⑫)
<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w" Version="2.0" IssueInstant="2013-03-18T03:28:54.1839884Z" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://www.contoso.com</Issuer> </samlp:AuthnRequest>
ID は、応答の InResponseTo に入って戻ってきます。Issuer は、Entra ID に登録した識別子と完全に一致している必要があります。要求に ACS URL(AssertionConsumerServiceURL)を入れる場合は、登録した応答 URL と同じでなければなりません。要求への署名は任意ですが、Entra ID 側で「署名された要求だけ受け付ける」設定にもできます。
次に、Entra ID が返すアサーションのうち、使える時間とあて先を示す部分です。
アサーションの Conditions の例(図12の⑰)
<Conditions NotBefore="2013-03-18T07:38:15.128Z" NotOnOrAfter="2013-03-18T08:48:15.128Z"> <AudienceRestriction> <Audience>https://www.contoso.com</Audience> </AudienceRestriction> </Conditions>
Audience には、AuthnRequest の Issuer と同じ値(アプリの識別子)が入ります。NotOnOrAfter は NotBefore の70分後です。Entra ID は、自分とアプリの時計のずれを見込んだ余裕を足さないので、アプリのサーバの時刻がずれていると、ここで失敗することがあります。アサーションの Issuer は https://sts.windows.net/ のあとにテナント ID が付いた値で、署名にはメタデータの IDPSSODescriptor にある鍵が使われます。
アサーションの AttributeStatement の例(図12の⑰)
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
<AttributeValue>testuser@contoso.com</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
<AttributeValue>3F2504E0-4F89-11D3-9A0C-0305E82C3301</AttributeValue>
</Attribute>
...
</AttributeStatement>
name の属性には利用者のユーザー名(UPN)が、objectidentifier には Entra ID の中で変わらない利用者の ID が入ります。名前やメールアドレスは変わることがあるので、アプリで利用者を見分けるには変わらない値を使うのが安全です。
アサーションの AuthnStatement の例(図12の⑰)
<AuthnStatement AuthnInstant="2013-03-18T07:33:56.000Z" SessionIndex="_bf9c623d-cc20-407a-9a59-c2d0aee84d12"> <AuthnContext> <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef> </AuthnContext> </AuthnStatement>
AuthnInstant は利用者が Entra ID で認証した時刻、AuthnContextClassRef は認証の方法です。複数の方法で認証したときは、いちばん強い方法が入ります。
どれを選ぶか
Entra ID は SAML も OpenID Connect も使えます。そのうえで Microsoft は、アプリが OpenID Connect と OAuth 2.0 に対応していればそちらを選び、対応していない既存のアプリには SAML を選ぶよう案内しています。
新しく作るアプリなら、OpenID Connect が第一の候補です。Microsoft は OpenID Connect 向けに MSAL や Microsoft.Identity.Web などのライブラリを出していますが、SAML のアプリを作るためのライブラリは出していません。SPA やモバイルアプリはブラウザや端末の中で動くので、JSON と REST で扱える OpenID Connect が向いています。一方で、SAML は企業向けの SaaS で長く使われていて、アプリが SAML にしか対応していない場合や、取引先や調達の条件で SAML が求められる場合には、SAML を選びます。
よくある間違い
| 間違い | どうするか |
|---|---|
| SAML のアサーションで API を呼ぼうとする | アサーションはアプリ(SP)あて。API を呼ぶには OAuth 2.0 のアクセストークンを使う |
| 署名だけ確かめて、Audience や期限を見ない | 別の SP あてや期限切れのアサーションを受け入れてしまう。Recipient・Audience・期限・InResponseTo も確かめる |
| 証明書の期限を誰も見ていない | 期限が切れるとアプリにサインインできなくなる。通知先に配布リストを入れ、更新の手順を決めておく |
| 新しく作るアプリに、なんとなく SAML を選ぶ | 新しいアプリは OpenID Connect を使う。SAML はアプリや相手が求めるときに選ぶ |
| IdP から始める流れにしたいのに、サインオン URL を入れたままにする | マイアプリのタイルがアプリのサインインページに移り、SP から始める流れになる |
うまくいかないとき
| エラー・症状 | 意味 | 確かめること |
|---|---|---|
| AADSTS750054 | 要求に SAML の要求(SAMLRequest)が入っていない | アプリが HTTP Redirect で AuthnRequest を送っているか。IdP から始める流れにしか対応していないアプリに、サインオン URL を入れていないか |
| AADSTS50011 | 応答 URL が登録と合わない | 要求の AssertionConsumerServiceURL が、応答 URL の一覧にあるか |
| AADSTS700016 | アプリが見つからない | 要求の Issuer と、登録した識別子(Entity ID)が完全に一致しているか |
| AADSTS50105 | 利用者がアプリに割り当てられていない | Users and groups の割り当て。グループなら、利用者が直接のメンバーか |
| アプリ側で署名エラー | アプリが持っている証明書と、署名に使われた証明書が違う | 証明書を更新したあと、新しい証明書をアプリに登録したか。期限が切れていないか |
| アプリ側で時刻のエラー | アサーションの使える時間の外と判断された | アプリのサーバの時刻がずれていないか |
企業での例
| 場面 | やること | 押さえどころ |
|---|---|---|
| 社員が業務の SaaS に Entra ID のアカウントでサインインする | ギャラリーからアプリを追加し、設定ガイドに沿って SAML を設定する | 識別子・応答 URL・証明書の交換と、証明書の期限の通知先 |
| AD FS で SAML 連携していたアプリを Entra ID に移す | アプリ側の IdP の設定(Issuer・SSO の URL・証明書)を Entra ID の値に替える | Issuer は https://sts.windows.net/ にテナント ID が付いた形になる |
| 自社で新しく社内ポータルを作る | OpenID Connect でサインインを組み込む | Microsoft のライブラリが使える。SAML は選ばない |
| ポータルに、サインインした人の予定も出す | OAuth 2.0 で Graph のアクセストークンをもらう | サインイン(ID トークン)と API(アクセストークン)の役目を分ける |
まとめ
| 項目 | 内容 |
|---|---|
| 答える問い | OAuth 2.0 は「何をさせてよいか」(認可)。OpenID Connect と SAML は「誰がサインインしたか」(認証) |
| 片方でしかできないこと | Web アプリのシングルサインオンはどちらでもできる。API のトークン・SPA とモバイル・マルチテナント(Entra ID)は OIDC。SAML だけの相手とつなぐ・IdP から要求なしで送る・管理画面での暗号化(Entra ID)は SAML |
| 書き方 | OpenID Connect は JSON(JWT)の ID トークン。SAML は XML のアサーション |
| 届け方 | SAML はアサーションがブラウザを通って POST で届く。署名が必須 |
| SP が確かめること | 署名・Issuer・Audience・Recipient・期限・InResponseTo |
| Entra ID の設定 | 識別子・応答 URL を登録し、ログイン URL・識別子・証明書をアプリに渡す。証明書はアプリごとで既定3年 |
| 選び方 | 新しいアプリ・SPA・モバイルは OpenID Connect。API は OAuth 2.0。SAML はアプリや相手が求めるとき |
参考にした資料
この記事は、次の標準と公式ドキュメントで内容を確かめて書きました。仕様や対応状況は変わることがあるので、最新の情報はリンク先で確かめてください。
- Security Assertion Markup Language (SAML) V2.0 Technical Overview(OASIS):SAML がセキュリティの情報をやり取りする枠組みであること、IdP と SP、3種類の文、SP から始める Web Browser SSO の流れ、メタデータ
- Profiles for the OASIS Security Assertion Markup Language (SAML) V2.0(OASIS):HTTP POST で届けるアサーションの署名が必須なこと、Response に入れるもの、SP が確かめること、IdP から始める応答に InResponseTo を入れないこと、RelayState
- RFC 6749: The OAuth 2.0 Authorization Framework(IETF):OAuth 2.0 が API を使う権限を受け取るしくみであること、発行年
- OpenID Connect Core 1.0(OpenID Foundation):OAuth 2.0 の上の ID の層であること、発行年、ID トークンを暗号化できること(2章)、第三者からサインインを始めるときはアプリに要求を送らせること(4章)
- Single sign-on SAML protocol(Microsoft Learn):要求は HTTP Redirect、応答は HTTP POST で届くこと、AuthnRequest と応答の例、Issuer・Audience・NotOnOrAfter(70分)・時計のずれ、属性、AuthnContextClassRef
- Federation metadata・Configure SAML-based single sign-on for your application using Microsoft Graph(Microsoft Learn):メタデータの窓口と IDPSSODescriptor、アプリごとのメタデータ URL の形
- Enable SAML single sign-on for an enterprise application・Enable single sign-on for an enterprise application with a relying party STS(Microsoft Learn):基本的な SAML 構成の項目、証明書とメタデータのダウンロード、マルチテナントのアプリでは設定できないこと、識別子がテナント内で重複できないこと、テスト
- Tutorial: Manage certificates for federated single sign-on(Microsoft Learn):自動で作られる証明書の有効期間(3年)、通知メール(60・30・7日前、5件まで)、更新の手順
- Scenario – Using Microsoft Entra ID to secure access to SAP platforms and applications・What is application management in Microsoft Entra ID?(Microsoft Learn):SAML の署名用の証明書がアプリごとであること、既定の署名が SHA-256 であること
- Validate a SAML single sign-on app for Microsoft Entra App Gallery onboarding(Microsoft Learn):IdP から始める流れとマイアプリ、サインオン URL の影響、属性とクレーム、AADSTS750054・50011・700016
- Error AADSTS50011 with SAML authentication・Error AADSTS50105・Error AADSTS750054(Microsoft Learn):応答 URL の不一致、割り当てのエラーとグローバル管理者が対象外なこと、SAML の要求が見つからないときの原因
- Configure Gainsight for Single sign-on with Microsoft Entra ID(Microsoft Learn):アプリ側の利用者を、シングルサインオンの前に作っておくこと(アプリごとの設定ガイドの例)
- Configure Microsoft Entra SAML token encryption(Microsoft Learn):SAML のアサーションを暗号化できること、P1・P2 の機能であること、管理画面の設定が SAML のアプリだけを対象にしていること
- Plan your SSO integration with Microsoft Entra ID (ISVs)(Microsoft Learn):SPA とモバイルアプリには OIDC が必要なこと、Web アプリは両方使えること
- SAML versus OpenID Connect: Choose the right SSO protocol・Plan a single sign-on deployment(Microsoft Learn):SAML と OIDC の比較、選び方
- Authenticate applications and users with Microsoft Entra ID・Authentication vs. authorization(Microsoft Learn):SAML の開発用ライブラリがないこと、新しいアプリに OIDC を勧めること、アーティファクトに対応していないこと、SAML bearer assertion flow
- SAML-based single sign-on: Configuration and Limitations(Microsoft Learn):AD FS から移すときの値の対応、Entra ID の Issuer の形
あとがき
3つを並べてみると、SAML と OpenID Connect は「誰か」を伝える点では同じで、違うのは書き方と届け方なのだと分かりました。とくに SAML は、アサーションがブラウザを通って届くので、署名と Audience・Recipient・期限の確認がそのまま安全を支えている、というところは図にしてみてはっきりしました。次の記事からは、API の通信そのものを守る TLS の話に進みます。
コメント