SAML とは ~基本的な構成例~
SAML (読み方:さむる) とは Security Assertion Markup Language という、Web アプリのシングルサインオン (SSO) を実現する XML ベースの規格です。
SAML は IdP (ID Provider: ユーザ ID を提供するもの) と呼ばれるサーバが中心となり、Assertion (SSO の肝となる認証トークン) の発行など SAML のやり取りを司ります。IdP のユーザ情報を格納するバックエンド DB として LDAP サーバを使うことが可能です。LDAP ではユーザの認証情報を使うだけでなく、SAML で扱うユーザの属性情報も引っ張ってくることができます。
また、SSO で認証されるサーバを SP (Service Provider: Web サービスを提供するもの) と呼びます。SP は認証モジュールとして SAML に対応してさえいれば、他は通常の Web アプリでよいです。SAML 認証モジュールは IdP から発行された Assertion に含まれるデジタル署名の検証に成功すれば、その Assertion に記載されたユーザを認証成功とみなします。
Assertion とトークンの違い
SAML においては、Assertion とトークンは同じ意味になります。実際、RFC7522 冒頭に以下の記載があります。
The Assertion, an XML security token, is a fundamental construct of SAML that is often adopted for use in other protocols and specifications.
SAML のメリット
ひと昔前の SSO というと『リバースプロキシ型』や『エージェント型』等が主流でしたが、ここでの問題は「規格化されていないためうまく動作するかどうかを対象サーバごとに検証しなければならない」ことでした。特にリバースプロキシ型は URL が実際のものと異なるため全ての画面遷移を検証する必要がありました。
SAML により SSO を行うサーバ、SSO されるサーバのそれぞれでどのように振る舞えばよいかが明確に規定されたため、安定性が高まりました。さらに SSO されるサーバは『認証モジュール』だけ意識すればよいため、検証や動作確認も行いやすくなりました。うまく動作しないときはどちらが悪いか明確になるため、バグ修正も進みやすいです。
また、http でやり取りするため、Web アプリサービスとの親和性が高いです。最近はオンプレだけでなく SaaS やクラウドサービスでも Web アプリが主流ですので、それらとの相性が良いです。
まとめると、メリットとしては以下が挙げられます。
- 規格化されており SSO を行うサーバ、SSO されるサーバそれぞれの役割が明確で、動作の安定性が高い
- 最近の主流である Web アプリとの親和性が高い
SAML と Kerberos の違い, ハイブリッド AAD join
SAML の SSO の仕組みとしては Kerberos と似ていますが、SAML が Web アプリに特化しているのに対し、Kerberos は Windows のドメイン環境に特化したものです。また、動作や役割は似ていますが用語が異なったりします。
以下に比較表を示します。
SAML | Kerberos | |
---|---|---|
認証を行うサーバ | IdP (ID Provider) | DC (ドメインコントローラ) |
SSOで認証されるサーバ | SP (Service Provider) | ドメインメンバー Windows間のSSOに特化 |
SSOで認証されるための 環境条件 | お互いに信頼関係を結ぶこと | ドメイン参加していること |
対応プロトコル | http(s) WebのSSOに特化 | SPNEGOに対応した プロトコル (SMB,RDP,http等) |
認証後に別サーバへ SSOするためのトークン | SAML response のAssertion | Kerberos Service Ticket |
主なクライアント | ブラウザ | Windows OS |
この 2 つのプロトコルを同時に扱うのがハイブリッド Azure AD join です。
ハイブリッド Azure AD join とは、ある Windows 端末が Kerberos を司るオンプレミスの ActiveDirectory ドメインコントローラ配下にドメイン参加 (コンピュータアカウントとして登録) しつつ、SAML を司るクラウドサービスの Azure AD にも join (デバイス登録) した状態を指します。(昨今のクラウドサービスは基本的に Web サービスのため SAML との相性が良い)
ハイブリッド join した Windows はこの両方の SSO 機能によりオンプレの Windows サーバとクラウドの Web アプリをシームレスにセキュアなアクセスができるようになります。
SAML のシーケンス例
今回の例では主流の HTTP Redirect Binding という方式を例にシーケンスを見てみます。
その中でもさらに 2 つのパターンがあります。1 つが SP-initiated SSO、もう 1 つが IdP-initiated SSO です。なお、ここではその中でもさらに実装の一例を示しています。実際にはこれ以外にも IdP と SP 間が SOAP で直接やり取りするような定義もあります。(ただし、通信要件が増えるだけなのであまり実装されない傾向。)
詳細は以下 OASIS のドキュメントを参照ください。
sstc-saml-tech-overview-2.0-cd-02.pdf (oasis-open.org)
SP-initiated SSO と RelayState
AzureAD でも使われている SP-initiated SSO (HTTP Redirect/POSTBinding) のシーケンスの例を以下に示します。
特徴としては認証を開始するトリガーの画面が SP 側であることです。SP から IdP に http リダイレクトされ、そのあとまた SP に返されますが、このときは POST する必要があるので http リダイレクトは使えません。代わりに SAML Response を含めた POST 用 JavaScript を返し、その JavaScript が IdP から SP へ SAML Response (Assertion 含む) を送信します。
このケースでは SP は AuthnRequest を http リダイレクト先の http のクエリーパラメーター (?SAMLRequest=) に付与して返したあと、しばらくして別の TCP コネクションで SAML Response を受け取りますが、この紐づけ (セッション管理) は Cookie ではなく SAML の RelayState と呼ばれる情報を使います。
SAML AuthnRequest 送信時に RelayState を生成して一緒に送信し、IdP は SAML Response に RelayState を変更せずそのまま送り返します。これにより SP は受信した SAML Response がどの Request の応答なのかを知ることができます。
IdP-initiated SSO
次に、IdP-initiated SSO (HTTP POST Binding) のシーケンスの例を以下に示します。
特徴としては認証を開始するトリガーの画面が IdP 側であることです。IdP の画面から SP を選択する際に認証がトリガーされます。SP-initiated と同様、http リダイレクトにより IdP から SP へ SAML Response (Assertion 含む) が転送されています。
SAML の Assertion と証明書による認証の仕組み
シーケンスにある通り、SP は IdP から発行された Assertion と呼ばれるトークンを受信することで、その Assertion 内に記載されたユーザーを「認証して良いユーザだ」と判断します。
ただし、Assertion にはパスワードが含まれているわけではありません。そのため、単に Assertion を渡すだけでは成りすましや改ざんの恐れがあります。これを防ぐために、Assertion にはデジタル署名による Assertion の成りすまし改ざん防止を行っています。
デジタル署名には RSA や ECDSA 等が使われます。基礎知識としては以下をご参照下さい。
Assertion によるデジタル署名の生成および検証の流れは以下の通りです。
SAML Reponse には IdP が秘密鍵により生成したデジタル署名 (xml の SignatureValue タグ) が含まれています。SP#1 は事前に IdP を信頼する証として、デジタル署名を検証するためのデジタル証明書 [トークン署名証明書] がセットされていますので、その証明書の中にある公開鍵を使い、デジタル署名が正しいものか検証を行います。検証に成功したら Assertion に記載されたユーザを認証するわけです。
信頼関係を結ぶ=メタデータの交換
SAML における IdP と SP 間の信頼関係構築とは、つまるところメタデータの交換になります。メタデータとは、SAML での SSO を実現するための、自分の取扱い説明書みたいなものです。
IdP から [IdP メタデータ] を Export し、それを SP へ Import、逆に SP から [SP メタデータ] を Export し、それを IdP に Import します。
トークン暗号化
SAML は基本的に SSL/TLS で暗号化された状態で使われることを想定しています。が、さらなるセキュリティ向上のために、トークン (Assertion) を暗号化することもできます。つまり、トークン部分が二重で暗号化されるわけです。
トークンを暗号化するためには、Assertion での認証を行うための『トークン署名証明書』とは別に、『トークン暗号化解除証明書』を別途用意する必要があります。
SP 側でデジタル証明書 (公開鍵含む) と秘密鍵を生成し、証明書を IdP に持っていき、該当 SP 向けの『トークン暗号化解除証明書』として登録します。
すると IdP から SP へ Assertion を渡す際に共通鍵を生成し AES で暗号化しつつ、その共通鍵を RSA 公開鍵で暗号化し、SP へ一緒に渡します。SP は RSA 秘密鍵を持っていますので暗号化を解除し共通鍵を得て Assertion を復号します。(教科書通りのハイブリッド暗号方式)
なお、SSL/TLS (https) においては RSA は「デジタル署名」としては使われていますが、共通鍵を暗号化する用途では近年では使われません。というのも、前方秘匿性が無いためです。具体的には、悪意ある人が興味対象の https 通信を盗聴、保存しておき、何年か後に RSA 秘密鍵を (手探りもしくは流出により) 得た場合、全ての通信の共通鍵が解読されてしまうからです。(SSL/TLS の共通鍵を共有する手段では DH, ECDH といった「鍵ペアが (結果、共通鍵も) 定期的に変更される」アルゴリズムが使われ、万が一 DH 秘密鍵が流出しても解読される範囲は限定される)
一方、Assertion (トークン) については「そのとき」に使う認証情報であり、それを暗号化するのであれば、何年か後に解読されても影響ありません。「いま」認証するために必要な情報だからです。
そういう意味では、トークンを暗号化する方式としては前方秘匿性の無い、教科書通りのハイブリッド暗号方式でも差支えが無いと言えます。(繰り返しになりますが、そもそも SAML は SSL/TLS で暗号化されているのが前提であるため、そこまでシビアに考える話ではありませんが。)
コメント