2016年3月7日月曜日

[SAML/OpenID Connect]どうなる?Microsoft Passportを使った場合のacr/amr

こんにちは、富士榮です。

SAMLやOpenID ConnectではIdentity Provider(IdP)でユーザがどのような方法で認証されたのかをAssertionやid_tokenの中に含めてRelying Party(RP)へ連携を行います。

この目的は、RPがIdPから渡される認証手段を検査して、求めるLoA(Level of Assurance/保証レベル)を満たしているかどうかを判断し、ログインを許可するかどうかを判断させることにあります。例えば、決済に関するサービスであればパスワードを使った認証では不十分で多要素認証を求める、などの判断を行います。

では、Azure ADに参加したWindows 10のPCにログオンし、Microsoft Passportを使ってアプリケーションへシングルサインオンした場合、IdPであるAzure ADはRP(アプリケーション)へどのような値を連携するのでしょうか?Microsoft Passportを使うということは、Azure ADへのログオン時に一切パスワードを使っていません。
(ついでに言うと今回のテスト時、PCへのログオンはWindows Helloを使ったので、PCへのログオン時にもパスワードは一切使っていません)

早速見てみましょう。
今回は、SAMLおよびOpenID Connectに対応したアプリケーションを用意し、fiddlerで実際にどのような値が渡ったのかを覗いてみます。

◆SAMLとOpenID Connectにおける認証手段の表現方法

まずSAMLとOpenID Connectにおける認証手段の表現方法を確認しておきましょう。

  • SAML
    • AuthnContextのAuthnContextClassRef属性を利用します。例えば、パスワードで認証されたことを示す場合は、[urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport]がセットされたり、AD FSなどを使って統合Windows認証が使われた場合は[urn:federation:authentication:windows]が使われたりします。
  • OpenID Connect
    • (2016/03/07追記)SAMLと同じくacr(Authentication Context Class References)を使います。OpenID Connectにおいてはid_tokenの中に値が設定されます。が、現状Azure ADにおいてはacrはセットされないようです。(B2Cテナントにおいては何故か固定値[b2c_1_sign_in]がセットされます)
    • id_tokenの中のamr(Authentication Methods References)クレームを利用します。どのような値が使われるかはプロトコルの規定外ですが、パスワードで認証された場合は[pwd]が使われたりします。



◆SAML対応アプリケーションへ渡されるAssertionを覗いてみる

では、早速SAML対応のアプリケーションへログオンしてみます。
Azure ADに参加したWindows 10のPCへAzure ADユーザでログオンし、アクセスパネル(https://myapps.microsoft.com)をMicrosoft Passportに対応したブラウザ(今回はEdgeを使いました)でアクセスします。


Microsoft Passportが有効なので、パスワードを入力することなくアクセスパネルが開きますので、SAMLに対応したアプリケーション(今回はGoogle Appsを使います)を開いてみます。

このとき、fiddlerを立ち上げて通信をキャプチャしておき、Google AppsのAssertion Consumer Service(www.google.com/a/ドメイン名/acs)へPOSTされるSAMLResponseを拾います。


拾ったSAMLResponseはSAML AssertionをBase64URL Encodeしたものなので、Decodeしてから目的のAuthnContextClassRefを探します。
ちなみに、SAML2 debuggerというサイトを使うとSAMLのメッセージをEncode/Decodeできるので便利です。
 参考)SAML2 Debugger
   https://rnd.feide.no/simplesaml/module.php/saml2debug/debug.php



結果、[urn:oasis:names:tc:SAML:2.0:ac:classes:Password]が入っています。
パスワードで認証したわけではないのに、パスワードで認証されたことになっている、ということです。
Azure ADを使ってSAMLアプリケーションにログインする場合は、どんな認証手段を使ったかについてはあてにならない、ということですね。


◆OpenID Connectアプリケーションへ渡されるid_tokenを覗いてみる

次は、OpenID Connectです。
SAMLの場合と同じく、Azure ADと連携したアプリケーションへMicrosoft Passportが有効な環境でログオンしてみます。

id_tokenをアプリケーションへ渡す方法(response_mode)も色々ありますが、今回のアプリケーション(自作)ではAzure ADの初期値であるform_postでid_tokenを渡しているので、Azure ADでログオンを行うとformを含むhtmlがダウンロードされ、JavaScriptで自動的にformデータがPOSTされます。
fiddlerで見ると、こんな感じに見えます。


このid_tokenの中身を覗いてみます。今度はJSON Web Token(JWT)なので、decodeするとPayload部分のJSONに各種クレーム(属性)が出てきます。

SAMLではSAML2 Debuggerを使いましたが、OpenID Connectの場合はjwt debuggerを使います。
 参考)jwt debugger
   http://jwt.io/

こんな感じで出力されます。

amrクレームの値を見ると、[pwd]と[rsa]の2つの値が入っています。
SAMLの場合と異なり、一応署名検証を使った認証を使ったことも認識されているようです。
(実際には使っていないパスワードも使ったことになっていますが)


ちなみに、Microsoft Passportが無効な環境で同じアプリケーションにアクセスした場合は[pwd]のみしかamrクレームに入ってきませんので、一応認証方式が異なることを表現してはいるようです。

こちらが、Microsoft Passportなしでログインした場合のamrの値です。



◆結論?

現段階において、Azure ADと連携するアプリケーションを開発する場合は、SAMLにおけるAuthnContextClassRefやOpenID Connectにおけるamrを見て認証方式や強度を判断するのは困難なようです。(OpenID Connectの方が若干マシですが、pwdが残ってるのは?です)


いずれにしても、想定している認証手段でログオン~ID連携が行われた場合にアプリケーションがどのような値を受け取るのか?についてはテスト段階で十分に検証を行っておく必要がありますね。





0 件のコメント: