SAMLとは?
SAML(Security Assertion Markup Language)は、「1回のログインで複数サービスを使える」SSO体験を実現するための仕組みです。ログイン結果を安全に受け渡すルールで、XML形式でやりとりされます。ここでは専門用語をなるべく避け、ざっくり理解できるように説明します。
🔐 SAMLの概要
SAMLは「ログイン結果」を安全に受け渡しするための決まりごとです。キーワードは以下の3つだけ覚えればOKです。
主要な登場人物
- 📌 IdP(アイディーピー):ログインを担当する「認証サーバー」。社員ポータルやGoogle Workspaceなどがここに当たる。
- 📌 SP(エスピー):実際に使いたいアプリ側。IdPが「この人はログインOK」と認めたら通してくれる門番。
- 📌 アサーション:ログイン結果を包んだメモ。XMLで書かれ、改ざんされていないかをチェックできる。
🔁 SAMLの通信の流れ
大まかには「SPがIdPに紹介状を依頼し、IdPが結果を返す」流れです。ブラウザ経由で往復します。
主なステップ
- ➡️ ユーザーが「使いたいサービス(SP)」にアクセスする
- ➡️ SPが「この人は誰?」というリクエスト(SAMLRequest)を作り、ブラウザをIdPへ送る
- ➡️ ユーザーがIdPでログインする(ID・パスワードや多要素認証など)
- ➡️ IdPがログイン結果をSAMLResponseとして作り、ブラウザ経由でSPへ送り返す
- ➡️ SPが信頼済み鍵で署名を検証し、発行元・宛先・期限・要求との対応・再利用も確認してからログインを成立させる
📨 SAMLRequest
認証時にはAuthnRequestを送ります。SAMLRequestは伝送パラメータ名で、LogoutRequest等にも使われます。符号化はバインディングで異なります。
特徴
- 🔍 SP → IdP への「紹介状をください」リクエスト。URL(Redirect)やフォーム(POST)で送られる。
- 🔍 POSTはXMLをBase64化。Redirectの標準エンコーディングはraw DEFLATE、Base64、URLエンコードの順。
- 🔍 署名の要否はIdPポリシー次第(要求される場合は署名する)。
SAMLRequestの例
最小限のAuthnRequestの例(署名や暗号化は省略)。
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="_req123" Version="2.0" IssueInstant="2024-01-01T00:00:00Z"
Destination="https://idp.example.com/sso" AssertionConsumerServiceURL="https://sp.example.com/acs">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://sp.example.com/metadata</saml:Issuer>
</samlp:AuthnRequest>
Base64 / Redirect例
HTTP-Redirectの標準エンコーディングはraw DEFLATE圧縮 → Base64 → URLエンコードです。下は構成の模式図で、括弧内を実際の生成値で置き換えます。
https://idp.example.com/sso?SAMLRequest={URL_ENCODED_BASE64_RAW_DEFLATE}
📄 SAMLResponse
IdPからSPへ返す認証結果。通常は署名され、必要に応じてAssertionが暗号化されます。
特徴
- 🔍 IdP → SP の「この人はOKです」回答。通常は署名つきで改ざんチェック可能。
- 🔍 Base64エンコードされたXMLとして返送され、POST(多くはPOST)で届く。
- 🔍 署名による完全性保護と、暗号化による秘匿は別の要件。暗号化しても検証は省略できない。
SAMLResponseの例
構造を読むための署名なし例です。実運用では署名を追加し、一意なID・現在の日時・宛先に置き換えます。この例をログインに受け入れてはいけません。
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Version="2.0" ID="_res123"
IssueInstant="2024-01-01T00:00:05Z" Destination="https://sp.example.com/acs" InResponseTo="_req123">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://idp.example.com/metadata</saml:Issuer>
<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_assert123" IssueInstant="2024-01-01T00:00:05Z">
<saml:Issuer>https://idp.example.com/metadata</saml:Issuer>
<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 Recipient="https://sp.example.com/acs" InResponseTo="_req123"
NotOnOrAfter="2024-01-01T00:05:05Z" />
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2024-01-01T00:00:05Z" NotOnOrAfter="2024-01-01T00:05:05Z"><saml:AudienceRestriction><saml:Audience>https://sp.example.com/metadata</saml:Audience></saml:AudienceRestriction></saml:Conditions>
<saml:AuthnStatement AuthnInstant="2024-01-01T00:00:00Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
Base64 / POST例
HTTP-POSTバインディングでは、Base64化したレスポンスをformに載せて自動送信します(例示用ダミーデータ)。
<form method="post" action="https://sp.example.com/acs">
<input type="hidden" name="SAMLResponse" value="PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm4... (Base64レスポンス)..." />
<input type="submit" value="Send" />
</form>
🌐 SAMLが使われる場面
「社内ポータルに入ったら他サービスもそのまま使える」ような体験を作るのに向いています。
利用例
- ✅ 社内システムとクラウドサービスのシングルサインオン連携
- ✅ Google WorkspaceやMicrosoft 365と外部アプリの連携
- ✅ IdPの認証結果を使い、各SPが独立したセッションを作る場合
仕様と関連する解説
OASIS SAML core / OASIS SAML bindings / OASIS SAML profiles
関連するSAML解説