1. ログインが何度も求められる問題
会社に入社すると、業務SaaSをいくつも使うようになります。もしSaaSごとにID・パスワードを登録していたら、パスワードの使い回し、退職時のアカウント削除漏れ、二要素認証の設定不統一などの問題が生じます。
そこでSSO(Single Sign-On)を導入します。社内の認証基盤で本人確認を行い、複数の外部サービスでその認証結果を利用できるようにします。これを組織をまたぐフェデレーション(認証連携)と呼びます。
IDENTITY & ACCESS MANAGEMENT
社内PCでポータルへ一度ログインすると、勤怠管理や経費精算など別会社のクラウドサービスにも入れる。なぜクラウドサービスへパスワードを渡さずに「本人だ」と伝えられるのでしょうか。
会社に入社すると、業務SaaSをいくつも使うようになります。もしSaaSごとにID・パスワードを登録していたら、パスワードの使い回し、退職時のアカウント削除漏れ、二要素認証の設定不統一などの問題が生じます。
そこでSSO(Single Sign-On)を導入します。社内の認証基盤で本人確認を行い、複数の外部サービスでその認証結果を利用できるようにします。これを組織をまたぐフェデレーション(認証連携)と呼びます。
| 登場人物 | 役割 | 身近な例 |
|---|---|---|
| ブラウザ(利用者) | アクセス・リダイレクト・フォーム送信を行う | 従業員が使うChromeなど |
| IdP(Identity Provider) | 本人確認を実施し認証結果を発行する | 企業の認証基盤 |
| SP(Service Provider) | 認証結果を検証して業務サービスへのセッションを作る | 勤怠・経費・グループウェア |
| ディレクトリサービス | 利用者ID、属性、認証に必要な情報を管理する | Active Directoryなど |
IdPとディレクトリは概念上別です。IdPがディレクトリの利用者情報を参照して本人確認する場合もあれば、認証機能を内包したサービスをIdPとして使う場合もあります。
大切なのは、SPが利用者のパスワードを受け取る必要がない点です。SPは「信頼するIdPが、誰を、いつ認証したと主張しているか」を検証します。
まず利用者が業務SaaS(SP)へアクセスします。SPにログイン済みのセッションがなければ、SPは認証要求(AuthnRequest)をブラウザ経由でIdPへ送ります。IdPは必要ならパスワードやMFAで本人確認を行います。
成功するとIdPはSAMLアサーションを含むSAMLResponseを作り、署名して、ブラウザにHTMLフォームを返します。ブラウザがフォームをSPのACS(Assertion Consumer Service)へPOSTし、SPは署名や宛先・期限などを検証してセッションを作ります。
SAMLはXMLを用いる仕様です。アサーション(Assertion)は「この利用者についてIdPがこう主張する」という認証に関するデータを含みます。例えば利用者の識別子、認証した時刻、認証方式、属性、SP向けの条件などです。
<!-- 学習用に大幅に省略した模式XML。実際の署名構造ではありません -->
<saml:Assertion ID="_sample123" IssueInstant="...">
<saml:Issuer>https://idp.example.com</saml:Issuer>
<saml:Subject>
<saml:NameID>user123</saml:NameID>
</saml:Subject>
<saml:Conditions NotBefore="..." NotOnOrAfter="...">
<saml:AudienceRestriction>
<saml:Audience>https://app.example.com</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="..." />
</saml:Assertion>本番で使うSAMLResponseにはXML名前空間、SubjectConfirmation、署名などさらに多くの要素があります。署名はResponseかAssertion、または両方に付される構成があり、どこを検証すべきかはプロファイルと信頼設定に従います。
SAMLは「暗号化されたパスワードを送る方式」ではありません。SSOに必要な認証の主張を、検証可能なメッセージとして伝える技術です。
会社のディレクトリがパスワードを管理し、IdPが利用者を認証している構成なら、クラウドSaaSはパスワードを知る必要がありません。IdPの署名付き主張を検証し、それを基にログインセッションを作るからです。
ただしパスワードがシステムのどこにも送信されないという意味ではありません。利用者がIdPのログイン画面に入力する場合、資格情報はIdP側の認証処理へ送られます。重要なのはSPに渡さないことです。
| データ | 通常のWeb SSOでの扱い |
|---|---|
| パスワード | IdP側で認証するための情報。SPへ送る必要はない |
| AuthnRequest | SPがIdPへ認証を要求するメッセージ |
| SAMLResponse | IdPが作成した応答。ブラウザ経由でSPに届く |
| アサーション | 利用者の識別や認証状況などに関するIdPの主張 |
| SPセッションCookie | SPが検証成功後に発行するログイン維持用の情報 |
| 方式 | 操作の始まり | 実務上のポイント |
|---|---|---|
| SP-Initiated | 利用者が業務SaaSのURLへアクセス | SPがAuthnRequestを作れるためInResponseToで対応づけやすい |
| IdP-Initiated | 利用者が社内ポータルからSaaSを選ぶ | 事前の認証要求がないため、要求との照合ではなく別の対策が重要 |
どちらもブラウザ経由でSAMLの結果をSPへ渡す形が代表的です。ただしSAMLにはHTTP Artifactなど別のバインディングもあり、すべてのメッセージの実体が必ずブラウザを通るとは限りません。この記事の図は最も理解しやすいRedirect/POST構成です。
ブラウザが運んでくるXMLを無条件で信じてはいけません。ブラウザ上のデータは攻撃者が改ざんする可能性があります。SPは、事前に信頼を設定したIdPの署名鍵に対応する公開鍵を用いて電子署名を検証し、署名された内容だけを権限判断の根拠にします。
SAMLメタデータには、エンティティID、送信先エンドポイント、署名検証用証明書などの連携情報を記述できます。導入時には双方でエンティティID・ACS URL・証明書などを整合させます。
SAMLResponseをBase64デコードできたことと、内容が真正であることはまったく別です。| 確認項目 | 防ぎたい問題 | SP側での対策例 |
|---|---|---|
| 署名と署名対象 | 偽造・XML署名ラッピング | 信頼した鍵で署名を検証し、検証済みの要素のみ参照する |
| Issuer / Audience | 別組織・別サービス宛ての流用 | 発行者、AudienceRestriction、Recipientを照合 |
| Destination / ACS | 意図しない場所への送付 | 正規の宛先とエンドポイントを検証 |
| 時間条件 | 期限切れの応答の再利用 | NotBefore、NotOnOrAfterなどを検証 |
| InResponseTo | 他のログイン要求への応答の転用 | SP起点なら保存した要求IDと一致させる |
| Assertion ID | 同じアサーションの再送 | 使用済みIDの再利用を拒否する(リプレイ対策) |
| セッション | セッション固定・盗難 | HTTPS、Secure/HttpOnly/SameSite等のCookie設定 |
現実には署名検証、条件検証、アカウント紐付け、セッション生成まで一体で安全に実装する必要があります。SAMLを独自にパースするより、十分検証されたライブラリや製品を正しく設定するほうが安全です。
認証(Authentication)は「誰なのかを確認する」こと、認可(Authorization)は「何を操作してよいかを決める」ことです。IdPが認証に成功したとしても、経費SaaSで承認権限を持つとは限りません。
SPはSAMLアサーションに含まれる識別子や属性を使い、既存アカウントへの対応づけ・アカウント作成・ロール付与などを行うことがあります。ただし属性があるだけで許可してよいわけではなく、SP側の認可ポリシーが必要です。
| 技術 | 主な用途 | イメージ |
|---|---|---|
| SAML 2.0 | 企業間の認証連携・Web SSO | 署名付きXMLアサーションで本人確認の主張を渡す |
| OpenID Connect(OIDC) | Web・モバイルのログイン連携 | OAuth 2.0を基盤にIDトークン等を使う |
| OAuth 2.0 | API等へのアクセス権限の委譲 | 認可の枠組み。OAuth単体をログイン規格と混同しない |
| LDAP | ディレクトリへの問い合わせ・管理 | ユーザーや組織情報にアクセスするためのプロトコル |
例えば「社内ディレクトリの利用者を認証し、外部SaaSにSSOしたい」という要件なら、IdPがディレクトリを参照して認証し、SPとはSAMLで連携するという組み合わせが成立します。技術が一つだけに置き換わる話ではありません。
社内SSOの導入では、ログイン成功だけで完了とせず、実際の運用を考えます。たとえば証明書の期限切れで全社員が入れなくなる、従業員のメールアドレス変更で別アカウントに紐付いてしまう、障害時のログイン手段がなくなるといった事態があります。
まずSP起点のSSOを1ステップずつ進めて、ブラウザ・IdP・SPのどこで何が起きるか確認します。その後、署名・有効期限・Audience・リプレイ対策を切り替え、SPがアサーションを受け入れてよい条件を実験しましょう。
「次へ」を押して、認証を行う場所と認証結果を運ぶ場所を追ってください。ここではSP起点・HTTP Redirect/POSTの代表例をモデル化しています。
ステップ 1 / 6
ブラウザ → SP
従業員がクラウドSaaSを開きました。SPにはまだログインセッションがありません。
GET /dashboard
SPが受信した認証結果の条件を切り替えましょう。署名だけが正しくても、他の条件を確認しなければ安全ではありません。
受理可能(この単純化モデルでは)
すべての検証項目に合格しています。実際のSPでは、さらに主体確認やアカウント紐付けなどが必要です。
企業のIdPが社内ディレクトリを使って認証する場合、代表的なSAML Web SSOでクラウドSaaSへ運ぶのはどれでしょう?
※ ブラウザだけで完結する概念実験です。実際のIdP・SPへの通信や電子署名の暗号学的検証は行っていません。設定・バインディングによって通信形態は異なります。
企業内の認証サーバが利用者を認証し、クラウドSaaSがその認証結果を利用する構成を考えます。典型的なSAML WebブラウザSSOでは、認証成功後にIdPが生成したSAMLResponseをブラウザがSPへ渡します。したがって、クラウドSaaSがディレクトリからパスワードを取り寄せたり、IdPがパスワードをSPへ送ったりする必要はありません。
また「乱数とパスワードのハッシュを直接クラウド側に送る」という説明はチャレンジレスポンス方式を連想させますが、SAMLの基本的なSSOメッセージ交換の説明ではありません。
SAMLのポイントは、パスワードをサービスに預けず、認証したというIdPの主張をSPへ伝えることです。IdPは本人を認証し署名付きアサーションを発行します。SPはブラウザ経由などで受け取ったメッセージを検証し、利用者のセッションを確立します。
「ブラウザは配達役、IdPは本人確認役、SPは検証・利用許可役」と覚えると全体像が崩れません。実務では署名だけでなく、宛先・時刻・要求ID・再利用の検証、MFAや利用者管理まで整えて初めて安全なSSOになります。