2013年3月25日月曜日

[Office365]AD FS2.0以外でSSOに挑戦


先日の MS 安納さんのポスト「【IDM】Windows Azure Active Directory と Office 365 と外部 IdP の関係(予想)」を見て、ちょうど Windows Azure Active Directory(WAAD)の中身を調査していたところだったので、色々と試してみました。

やろうとしたことは、WAAD の Access Control Service(ACS)を経由して Facebook や Google アカウントを使った Office365 へのシングルサインオンです。
結果、失敗するのですが、その過程で色々と仕組みが想像できたのでメモとして上げて起きます。

■まずは情報収集
現在、サードパーティ IdP での WAAD / Office365 へのフェデレーションの例としては、以下のような設定ドキュメントが公開されています。

・Ping Federate  http://documentation.pingidentity.com/display/PFS/Set+up+Active+Directory+and+Directory+Synchronization#SetupActiveDirectoryandDirectorySynchronization-9000025
・Shibboleth
 http://technet.microsoft.com/ja-jp/library/jj205463.aspx

後は、AD FS2.0 でシングルサインオンを構成した WAAD / Office365 のドメイン設定がどうなっているのか、を直接調べるとことも参考になりそうです。

また、Offce365 のシングルサインオンに関するドキュメントを見ると Office365 側の前提事項なども見えてきます。
 https://portal.microsoftonline.com/IdentityFederation/IdentityFederation.aspx


調査の結果、WAAD / Office365 が外部 IdP とフェデレーションを行うには、以下が必要なことがわかります。

◆WAAD / Office365 側の状態
 - ディレクトリ同期が行われている状態であること
  こんな記載があります。
  シングル サインオン (ID フェデレーション) をセットアップすると、ユーザーは会社の資格情報でサインインして、Microsoft Office 365 for enterprises のサービスにアクセスできます。シングル サインオンのセットアップの一部として、ディレクトリ同期をセットアップする必要もあります。また、これらの機能をお使いの社内のディレクトリおよびクラウドのディレクトリに統合する必要があります。

 - シングルサインオンを有効にしたドメインを利用すること
  まぁ当たり前ですが、ログイン画面(https://login.microsoftonline.com/login.srf)でログイン ID のドメインパート(@以下)を判別して、ログイン先の IdP を判別する以上、WAAD / Office365 がシングルサインオンドメインとして認識しているドメインが必要です。

  ドメインの設定は Set-MsolDomainAuthentication コマンドレットを使うのですが、必要なパラメータは以下の通りです。
  - DomainName : ドメイン名
  - FederationBrandName : ブランド名(表示名)
  - ActiveLogOnUri : Active Logon をする場合のエンドポイント
  - IssuerUri : IdP の EntityID
  - PassiveLogOnUri : Passive Logon をする場合のエンドポイント
  - LogOffUri : ログオフする際のエンドポイント
  - MetadataExchangeUri : Metadata Exchange のエンドポイント
  - PreferredAuthenticationProtocol : 利用するフェデレーション・プロトコル
  - SigningCertificate : 署名に利用する証明書

  ちなみに AD FS2.0 と連携している WAAD / Office365 のドメインの情報を Get-MsolDomainFederationSettings コマンドレットで取得すると以下のような状態になっています。
パラメータ設定値
DomainNameドメイン名(コマンドレットの引数として指定)
FederationBrandNameFQDN
ActiveLogOnUrihttps://FQDN/adfs/services/trust/2005/usernamemixed
IssuerUrihttp://FQDN/adfs/services/trust
PassiveLogOnUrihttps://FQDN/adfs/ls/
LogOffUrihttps://FQDN/adfs/ls/
MetadataExchangeUrihttps://FQDN/adfs/services/trust/mex
PreferredAuthenticationProtocolWSFed(コマンドレットでは出ない)
SigningCertificatexxxxxx



◆外部 IdP の設定
 当然、外部 IdP 側には RP として WAAD / Office365 を設定する必要があリます。
 WAAD / Office365 の Federation Metadata が
  https://nexus.microsoftonline-p.com/federationmetadata/saml20/federationmetadata.xml
 で公開されているので、中身を見てみます。
 必要なのは、IdP から見ると Audience に該当する EntityID 部分とトークンを POST するアサーション・コンシューマ・サービスのエンドポイントアドレスです。
 Federation Metadata を見ていくと、
 - entityID="urn:federation:MicrosoftOnline"
 - AssertionConsumerService ~中略~ Location="https://login.microsoftonline.com/login.srf"
 とあります。

 あとは、使用するプロトコルですが、Set-MsolDomainAuthentication コマンドレットなどフェデレーションドメインの設定用ツールのオプションである PreferredAuthenticationProtocol がとりうる値を見ると、WSFed / SAMLP とあるので、WS-Federation もしくは SAML-P が可能なことがわかります。
 今回は ACS を使ったので、自動的に WSFed を選ぶことになりますが、その場合に SAML トークンのバージョンが気になります。FireFox の SAML Tracer などを使って AD FS2.0 と WS-Federation で連携している WAAD / Office365 との間を飛んでいる SAML トークンを見ると、
  saml:Assertion+MajorVersion="1"+MinorVersion="1"+AssertionID=xxx
 という記述が見えるので、 SAML トークンは 1.1 を使うことがわかります。

◆アサーション(クレーム)
 - AD FS2.0 の要求規則を見ると、以下のアサーション(クレーム)が発行されることが必要です。

AttributeTypeValue
nameidentifierhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifierAD上のオブジェクトのGUIDの値をbase64エンコードしたもの
UPNhttp://schemas.xmlsoap.org/claims/UPNAD上のオブジェクトのUserPrincipalName(xx@xx.com)
ImmutableIDhttp://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableIDAD上のオブジェクトのGUIDの値をbase64エンコードしたもの


  ちなみに、AD FS2.0 が実際にどのようなアサーションを出しているのかを確認する場合は、ClaimGrabber(http://www.theidentityguy.com/articles/2011/6/5/introducing-claimgrabber.html)を使うと便利です。


  当然、このアサーションの中のそれぞれの値が WAAD / Office365 上に同期されたユーザの属性と一致している必要があります。(特に NameIdentityfier として使われる ImmutableID の値が重要)
  ユーザの属性を調べるには Get-MsolUser コマンドレットを使います。
  こんな感じで、ImmutableID の値を取得します。
  > Get-MsolUser -UserPrincipalName xxx@xxx.com | fl ImmutableID
  すると、
  ImmutableId : VNzO5OVz+Emv66IULItTCg==
  という形で値が取得できます。



まとめると、以下が外部 IdP と WAAD / Office365 のフェデレーションの条件になりそうです。
対象条件
WAAD / Office365ディレクトリ同期構成済みであること
ドメインシングルサインオンドメインが構成されていること
外部 IdPRP の 識別子(EntityID)urn:federation:MicrosoftOnline
RP の エンドポイントhttps://login.microsoftonline.com/login.srf
プロトコルWS-Federation
SAML トークン形式SAML 1.1
アサーションNameIdentifierADのGUIDをBase64エンコードした値(Get-MsolUserで取得した値と一致していること)
ImmutableID同上
UPNADのUserPrincipalNameの値



■実際にやってみる
では、早速 ACS を使って上記を構成してみます。

◆WAAD / Office365
 ディレクトリ同期は普通に DirSync を使って構成します。
 具体的なやり方は、手前味噌ですが、
  @IT / Office 365とのアイデンティティ基盤連携を実現する(前)
  http://www.atmarkit.co.jp/ait/articles/1211/14/news069.html
 を参考にしてください。

 ドメインの設定ですが、ACS の Federation Metadata から取得した値を設定します。
 ACS の Federation Metadata は
  https://テナント名.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml
 なので、必要な値はここから取得します。
 といっても使うのは IssuerUri と PassiveLogOnUri と MetadataExchangeUri だけです。
 - IssuerUri : https://テナント名.accesscontrol.windows.net
 - PassiveLogOnUri : https://テナント名.accesscontrol.windows.net/v2/wsfederation
 - MetadataExchangeUri : https://waadnew1.accesscontrol.windows.net/v2/wstrust/mex

 これらの値を使って WAAD / Office365 上にドメインを構成します。
 まずは、ドメイン自体の作成です。
 > Connect-MsolService
 で WAAD / Office365 へ接続し、
 > New-MsolDomain -Name 作成するドメイン名 -Authentication Federated
 と打ってフェデレーションドメインを作成します。

 次に、ドメイン所有権の確認のための CNAME レコードの出力と作成です。
 > Get-MsolDomainVerificationDns -DomainName 作成したドメイン名
 ここで出てくる Label の値を DNS 上に登録します。

 登録が完了したら、確認と同時に IdP の設定もしてしまいます。

 > $domainName = "ドメイン名"
 > $brandName = "ラベル名"
 > $issuerUri = "https://テナント名.accesscontrol.windows.net"
 > $passiveLogOnUri = "https://テナント名.accesscontrol.windows.net/v2/wsfederation"
 > $logOffUri = "https://テナント名.accesscontrol.windows.net/v2/wsfederation"
 > $activeLogOnUri = "https://テナント名.accesscontrol.windows.net/v2/wsfederation"
 > $metadataExchangeUri = "https://テナント名.accesscontrol.windows.net/v2/wstrust/mex"
 > $signingCertificate = "xxxxxxxxxx"

 として引数を設定し、Confirm-MsolDomain コマンドレットを実行します。
 > Confirm-MsolDomain -DomainName $domainName -FederationBrandName $brandName -ActiveLogOnUri $activeLogOnUri -IssuerUri $issuerUri -PassiveLogOnUri $passiveLogOnUri -LogOffUri $logOffUri -MetadataExchangeUri $metadataExchangeUri -PreferredAuthenticationProtocol WSFed -SigningCertificate $signingCertificate


◆ACS の設定
 次は ACS の設定です。
 ACS の IdP の設定として Facebook や Google などを設定するのですが、ここでは詳細は省略します。Facebook の場合、Facebook 上にアプリを構成して Consumer Key と Consumer Secret を取得するのと、Callback URL に ACS を設定するだけです。

 ここでは RP 設定(証明書利用者アプリケーション)とクレーム・ルール(規則グループ)の設定を行います。
 まずは RP 設定は以下の通りです。
 - 領域 : urn:federation:MicrosoftOnline
 - 戻り先 URL : https://login.microsoftonline.com/login.srf
 - トークン形式 : SAML 1.1


 次にクレーム・ルールですが、どうやって Facebook などから AD の GUID を Base64 エンコードした NameIdentifier / ImmutableID を取得しようか、、という話になります。
 やり方としては実は ImmutableID は必ずしも AD の GUID を Base64 エンコードした値そのものでなくても良い、という点を利用します。ユーザを WAAD / Office365 に作っているのはディレクトリ同期ツール(つまり FIM2010)なので、ImmutableID(ディレクトリ同期ツール上では SourceAnchor)に Facebook から取得できる他の値に設定してあげればよいわけです。
 ACS が Facebook から取得するクレームとしては Facebook 上のユーザID(数字の羅列)があるので、それを ImmutableID として設定してしまいます。
 簡単なアプリケーションを作って ACS が Facebook から取得する nameidentifier の値を取得し、それを AD 上のどこか適当な属性の値に設定し、ディレクトリ同期ツールの属性マッピングの設定を変えてしまいましょう。

 と、正攻法?は上記なのですが、面倒なので、逆のアプローチもあります。
 AD と同期したユーザの ImmutableID の値を ACS が nameidentifier や ImmutableID として出力できればよいわけなので、ACS の出力要求の値に直接取得した ImmutableID の値を入れてしまいます。当然一人しか使えなくなりますが、実験なので良しとします。


ここまでで一通りの設定は終わりです。さっそく実験します。

■いざ、試す
結果、失敗します。



ここまでは順調。
そして失敗。。。


■原因を考えてみる。。
 正常に使える AD FS2.0 でのログオンの場合と、失敗する Facebook のパターンを比較してみます。
 Firefox の SAML Tracer を使って https://login.microsoftonline.com/login.srf に POST されるアサーションの中身を比較してみます。
 saml:AttributeStatement の中身はほぼ同じです。AD FS2.0 側は NameIdentifierに Format プロパティで urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified が設定されていますが、AD FS2.0 のクレーム・ルールのオプションを付ける部分を削除してもちゃんとログオンはできたのでここは原因ではなさそうです。

 しかし、そのままアサーションを見ていくと、、ありました、圧倒的な違いが。
AD FS2.0 の出力したアサーションには AuthenticationStatement が存在しますが、ACS の出力したアサーションには AuthenticationStatement がありません。
 確かに ACS 自体は認証をしている訳ではないので AuthenticationStatement が出力されるわけがありません。ちなみに ACS の IdP を Google にしても結果は同じなので、ACS の先の IdP がどうやって認証したのか?という情報は ACS からの出力クレームには含まれません。

 ということで、おそらく原因はこれです。
 尚、私はここであきらめたのですが、どなたかその先を深堀して出来れば解決してみて頂きたいなぁ、、と。


■実験を通しての感想
 ACS は非常に便利なのですが、クレーム・ルールの編集でできることが非常に少ないです。せめて AD FS2.0 の要求規則の編集程度のカスタマイズが出来れば色々と可能性が広がると思います。

2013年3月9日土曜日

[IdM用語]NASCAR問題


アイデンティティ界隈では普通に使われている言葉なのに Google 先生に聞いてみても答えが出てこない言葉って結構あったりします。
その一つが、「NASCAR 問題」です。

日本語でそのまま検索すると Wikipedia の OpenID のページに以下のように記述があります。

Account ChooserOpenID Authentication 2.0, OpenID Connect のみではなく、SAMLなどでも問題になる ユーザーインターフェースの問題 (NASCAR問題、WAIF問題)を解決すべく検討されている 仕様。

どうやらユーザーインターフェースの問題らしい、というところまではわかりますが、具体的にどういう問題なのか、NASCARって何なのか、についてはよくわからないままです。



というわけで簡単に解説です。(もっとうまく解説できる、もしくは違うよ、という方はご連絡・ツッコミください!)

簡単に言ってしまうと、
OpenID や SAML などで外部 IdP を使ってサービスへログオンするとき、IdP が増えてくるとユーザが自分がログオンに使う IdP を探し出すのが難しくなって利便性が下がってしまう
という問題です。
ログオンメニューに Facebook のアイコンや Twitter のアイコン、Yahoo! や Mixi や、、、という様にずらりと並んでいるのを見たことはないでしょうか?

例えば OpenID Foundation のページへログオンするときは以下の様に自分が使う OP(OpenID Provider)を選択することになります。



で、Account Chooser を使うと一回ログオンした IdP の情報を覚えておいてくれるので、毎回使ってもいない IdP が沢山並んでいる中から自分が使う IdP を選んでログオン、という手間が省けますよ、という流れです。
ちなみに Account Chooser 自体に関する情報は OpenID Foundation Japan の Evangelist である @nov 氏、 @ritou 氏が解説しているので、ここを参照してください。

- @IT の記事 by @nov 氏
 セキュアで使いやすい認証UX標準化を目指すAccount Chooserプロジェクト
 http://www.atmarkit.co.jp/ait/articles/1301/28/news010.html

- r-weblife by @ritou 氏
 GoogleでわかるAccount Chooser
 http://d.hatena.ne.jp/ritou/20111119/1321688092


で、NASCARって何なのか?だけが残ってしまいました。
NASCAR(ナスカー)とは National Association for Stock Car Auto Racing / 全米自動車競争協会のことです。

こんな車が走ってるレースです。


これとアイデンティティとの関係ですが、車を良く見ると各スポンサーのロゴステッカーが所狭しと並んでいるのが見えると思います。これって先ほどの IdP のロゴが並んでいるのと似てますよね?ということで、NASCAR みたいだから NASCAR 問題ということです。

他にも色々とマニアック用語がありそうなので、時々解説していこうと思います。

2013年3月5日火曜日

[JICS]なかなか面白いサービス「Trulioo」


昨日~本日開催されているJapan Identity & Cloud Summit(JICS)に参加しています。

学認、OpenID Summit、Enterprise、Trust Frameworkなど色々なコンテンツがそろっていてものすごい情報量です。


その中で併設された展示ブースに出展されていた「Trulioo」の話を聞いて非常に面白い、と思ったので少し紹介します。

◆サービス概要
簡単に言うと、「ソーシャルIDの信頼レベルを判定してくれるサービス」です。

各種サービスへのサインインやログインにFacebookなどのソーシャルIDを使う、というのはすでにかなりメジャーな方法になってきていますが、一方で昨今メディアなどでも取り上げられている「なりすましアカウント」や「使い捨てアカウント」などを使ってサービスを利用することによる被害(例えば偽アカウントで商品を注文したり、宿の予約をしたり)も問題視され始めています。

そこで、各サービスはFacebookでのログインをさせる前に、Truliooのようなサービス(API)を利用して信頼レベルを判定することで、リスクを低減することが出来ます。

内部的な判定ロジックは非公開ですが、FacebookのIDからサービス側で保持しているデータベース等を利用して信頼レベルを判定するようです。

このAPIを実行すると、結果として信頼レベルが0~400で返ってきます。


この結果を使って各種サービスは利用者アカウントに対する各種アクションを決めてく、という仕掛けです。


◆使い方
まずはTruliooにサインアップします
https://trulioo.com/ を開くと右下に[Wants To Try Our ProfilePlus API?]というボタンがあるので、[Register]をクリックし、各種情報を入力し、登録を行います。
※今はJICS特別サイトが用意されており、そこからだと更に登録が楽です。
 https://trulioo.com/jics/

登録が完了したら、Developerポータルへログイン出来るようになります。今回はテストなのであらかじめ用意されているテストツールを使って確認してみます。
右側のメニューからAPI Referenceを選択するとテストツールへアクセスできますので、このツールを使います。


このツールに設定するパラメータは、
・apikey
・provider(現状fb/facebook固定)
・token
の3つです。

まず、apikeyですが同じくDeveloperポータルのApp Setting & StatsのProfilePlus API Accessメニューから取得できます。


次にtokenですが、これはFacebook上のリソースへアクセスするためのaccess_tokenを設定します。
こちらもテストなので、FacebookのGraph APIエクスプローラを利用します。
Graph APIエクスプローラを開いた後、[アクセストークンを取得]ボタンをクリックし、必要な権限を設定し、アクセストークンを取得します。
必要になる権限は、
 ・email
 ・user_photos
 ・user_groups
 ・user_status
 ・user_videos
 ・user_events
 ・read_stream
です。


apikey,tokenを取得できたら先ほどのツールへ戻り、パラメータをセットして[Try it out!]をクリックします。
すると、判定結果がjsonで返ってきます。
どうやら私のFacebookアカウントの信頼レベルは400(Normal - High)なようです。


今回はテストでしたが、Request URLにapikey,provider,tokenを付けてGETするだけなので、簡単にサービスへ組み込みが可能です。
例えば、Windows Azure Active DirectoryのAccess Control Serviceを使ってFacebookのアクセストークンを取得して、Truliooで信頼性レベルをチェックしてからサービスを利用させる、といった形が簡単に実装できそうです。

◆課題
ここまで簡単な紹介をしてきましたが、ざっと使った中で少し課題と感じた部分を書いておきます。

・ユーザ同意の取り方
 先にも書きましたが、Truliooを使う上で必要なパーミッションとして、以下へのアクセスが要求されます。
 ・email
 ・user_photos
 ・user_groups
 ・user_status
 ・user_videos
 ・user_events
 ・read_stream

 しかし、Facebookへのアクセス時に表示される同意画面だけで「なぜその属性や情報が必要なのか?」を理解するのは中々厳しいのではないかと思います。(特にサービス自体を利用する上で不要と思われるものが多いため)
 と、いうことでサービス側の考慮点として、TruliooでFake Accountの判別をしていることをログイン画面などにしっかり記載しておき、なぜそれらの属性が必要なのかを利用者が理解できるようにしておくことが必要になるのではないかと思います。

◆まとめ
こんな感じです。
・ソーシャルIDでサービスを利用してもらう、というのはハウスリスト拡充の意味でも、サービス内でのアクティビティ向上の意味でも有意義である
・しかし、Fake Accountが多発するといった課題も抱えているのが実情である
・そこでアカウントの真贋レベルを確認するTruliooのようなサービスを使うのも一手である
・しかし、真贋を確認するために必要な情報の取得が発生するため、利用者に分かりやすい形での同意の取得を検討すべきである