2010年12月26日日曜日

ACSでWindowsLiveIDを使う場合に割と普通にはまるポイント

若干わかる人にしかわからないタイトルになっていますが、内容的にはFAQになりそうなポイントなのでいつも通り解説していきます。
環境を作る上での詳細な手順は以前紹介した内容割と普通さんの日記を参照してください。


■問題が発生する状況
AppFabric Access Control Service(ACS)を使って外部認証するアプリケーション(RP)を作りたい。※ACSはLab版
・認証(IdP)はWindows LiveIDを使いたい。

■問題
・Windows LiveIDで認証された後、クレームが取得出来ない(様に見える)
・Googleで認証するとうまくクレームの取得ができる

単純なWIFを使ったアプリケーションでPage_Loadで画面上にPage.User.Identity.Nameの値を表示するもの。











Googleで認証されると取得できる。













■原因は何か?
先に結論を言ってしまいますが、アプリケーションが使いたいクレームをWindows LiveIDが提供していないことが原因です。
通常クレームを使うアプリケーションは取得したクレームから利用者を特定するためにWIFによってプロパティに設定されるPage.User.Identity.Name変数を利用します。

しかし、この変数はClaimType=http://schemaes.xmlsoap.org/ws/2005/05/identity/claims/nameという型でクレームが発行されていないとセットされないので、Identity Providerがname属性のクレームを発行していないと変数には何も入りません。

ACSのClaim Ruleを見てみるとIdPにWindows LiveIDを選択するとInput Claim Typeにはnameidentifierの1種類しか選択できないことがわかります。













実際に発行されたトークンの中身を見てみてもnameidentifier以外のクレームは発行されていません。
トークンの中身を見るにはいくつか方法があるのですが、ここではCodePlexに公開されているSecurityTokenVisualizerを使います。(詳しい使い方は後日紹介します)











Googleで認証するとうまくいくのはGoogleがname属性を提供しているからです。













■ではどうしたら良いのか?

そもそも何故Windows LiveIDではnameidentifier以外の属性を発行していないのでしょうか?また、nameidentifier属性に入っている値は何を意味するのでしょうか?nameidentiferに入っている値から他の属性の値を取得することはできないのでしょうか?

答えはMSDNフォーラムにありました。

-----------------------------
For LiveId, the NameIdentifier is an unreversable hash of the user's Live PUID and is therefore not usable to get more information. This behavior is due to Windows Live privacy requirements. Currently one possible workaround is to manually add mapping rules to map the hash code to a specific username on ACS labs portal.
-----------------------------
要するに、
・nameidentifier属性にはWindows Live IDのPUID※のハッシュ値が入る
 ※account.live.comに表示される固有ID
・この値から他の属性の取得はできない
・これはWindows Liveのプライバシー上の理由からである
・ワークアラウンドとしては各nameidentifier属性に入るハッシュ値とユーザ名を手動でマッピングするしかない
ということです。

インターネット上のアイデンティティという話をするとどうしても避けて通れないプライバシーの問題に行き当たるようです。SAML2.0の仮名と同じ考え方ですが、特定のRPでしか使えない識別子を割り当てることによりそのユーザが他にどのようなRPを使っているかの特定、また他のRPへは提供されている属性を識別子をキーに収集して本人の同意がない形でアイデンティティを見える化されてしまうことを防ぐための仕様です。(これもまた別の機会に解説します)


結果的にフォーラムにもあるワークアラウンドを用いる形になりますが、何もACS側のマッピングにユーザの属性を個別にマッピングする必要はなく、「認証」と「ユーザ属性の管理」を分離して考えて、
・認証:Windows Live ID
・ユーザ属性の管理:アプリケーション
で実施するのが現実的だと思います。

具体的にはWindows Live IDで認証された後、取得できるPUID(のハッシュ値)をアプリケーション側のユーザテーブルと紐付けて、初めてのPUIDならユーザ情報を登録し、すでに存在するPUIDなら登録済みのユーザ情報をベースにアプリケーションを開始する、という流れになります。(Googleなど他の属性も取得できるIdPを使う場合はある程度の情報はユーザテーブルに初期値として登録してあげればよい)

このあたりはそのうちサンプルアプリケーションを作って公開でもしようかと思います。

0 件のコメント: