Windows Azure の ACS で認証トークン (FedAuth Cookie など) が Expire (期限切れ) になった場合の対処

(2012/05 : 「Windows Azure Active Directory」のブランド名にあわせて追記)

こんにちは。

拡充中の Windows Azure How-To 集 ですが、今週は、下記を公開しました。

デスクトップ (Windows) やスマートフォン (Windows Phone) で動くアプリケーションのようなブラウザー以外で動くクライアント アプリケーションから、Windows Azure Active Directory の Access Control Service (ACS) を使用した Web アプリケーション (サービスなど) を使用する場合は、アプリケーションに WebBrowser コントロールを貼り付け、このコントロールの上で複雑な認証 (ログイン等) を処理し、最後に受け取ったチケット (FedAuth Cookie、access_token など) を使用して以降の処理 (Web Api の呼び出し、など) が可能です。
上記の「WebBrowser コントロールで Windows Azure ACS を使用した認証を行う」では、この手順を解説してくれています。(Microsoft 以外の環境でも、同様のコントロールなどが提供されている場合には、同じ手法が使えます。)

こうしたブラウザー コントロールを使った手法や、以前解説した Active Authentication では、受け取ったチケットの有効期限 (expiration) に注意する必要があります。例えば、Windows Azure Active Directory の ACS では、既定で 10 分の有効期限が設定されいるため (この値は、変更可能です)、一定時間を経過すると、Web アプリケーション (サービスなど) への接続が拒否されるためです。
そこで今回は、こうした期限切れ (Expire) の問題をどのように解決すべきか補足 (解説) しておきます。

補足 : 実際には、設定値よりも、5 分ほど多く有効になっているようです。(このため、ACS のトークンは、既定で 15 分程度 有効です。)

補足 : 上記の「WebBrowser コントロール で Windows Azure ACS を使用した認証を行う」では、SWT を使用した場合を解説しています。SAML トークンを使用している場合は、同様に、WebBrowser コントロールでログイン処理をおこない、Navigate が完了したイベントを取得して、FedAuth Cookie を取得します。しかし、この FedAuth Cookie は、HTTPOnly 属性の Cookie のため、WebBrowser コントロールから .NET のコード (あるいは JavaScript など) を使って取り出すことができないので注意してください。
HTTPOnly 属性の Cookie をブラウザー コントロールから取得する方法については、Office 365 SharePoint Online の Programming による Authentication」に記載していますので、同様の方法で取得してください。(「プログラムから扱えないように保護しているのに、プログラムから扱う方法を紹介して良いのか ! ?」というツッコミがあるかと思いますが、ひとまず、目をつぶってください。)

 

Passive Authentication の場合 (一般的な流れの復習)

まず、Web ブラウザーによる一般的な Passive の処理が、どのように動作しているか復習しておきましょう。

基本的なことですが、一般の Web ブラウザーを使った Passive Authentication では、Windows Azure Active Directory (ACS) で保護された Web アプリケーションに接続をおこなうと、最終的に、FedAuth、FedAuth1 の 2 つの Cookie がブラウザーに設定されます。(SWT を使用している場合は、アクセス トークンがクライアントに渡されます。)
以降は、このチケット (Cookie など) を使用して Web アプリケーション (RP, Relying Party) に接続することで、Web アプリケーション (サービス) 側に設定されている WIF (Windows Identity Foundation) のフレームワークによってトークン (FedAuth Cookie) の検証がおこなわれ、問題なければ、要求された処理を実行します。(なお、SWT を使用している場合は、WIF の構成ではなく、開発者自らがトークンの検証処理を実装します。)

このチケット (FedAuth Cookie など) が期限切れになった場合は、Web アプリケーションに同じブラウザーで接続をおこなうと、以下の手順で処理されます。

  1. FedAuth、FedAuth1 の Cookie に空文字を設定します。また、Location ヘッダーを使って、https://<namespace&gt;.accesscontrol.windows.net/v2/wsfederation?wa=wsignin1.0&wtrealm=<id provider’s url>&wctx=<context info>& …(以降、省略)
    の Url にリダイレクトされます。
    なお、<context info> には、接続先の URL の情報などを含んでいます。(例えば、rm=0&id=passive&ru=%2fAbout.aspx の形式の文字列です。)

HTTP/1.1 302 Found
. . .
Location: https://<namespace&gt;.accesscontrol.windows.net/v2/wsfederation?wa=wsignin1.0&wtrealm=<id provider’s url>&wctx=<context info>& …
. . .
Set-Cookie: FedAuth=; path=/; expires=…
Set-Cookie: FedAuth1=; path=/; expires=…
. . .

  1. ブラウザーは、Windows Azure Active Directory の ACS 2.0 のアドレス (上記の https://<namespace&gt;.accesscontrol.windows.net/v2/wsfederation?wa=wsignin1.0&wtrealm=<id provider’s url>&wctx=<context info>& …) に飛びます。
    ここで、wa=wsignin1.0 は「実行アクションが SignIn である」ことを意味しています。このため、ACS は、Location ヘッダーを使って、ID Provider (AD FS, Windows Live, Google など) の Passive の SignIn URL にリダイレクトをおこない、いつものように SignIn を要求します。(この際、上記の <context info> も、そのまま ID Provider に渡されます。)
  2. ID Provider (AD FS など) では、いつものように Sign-In (ログイン) の画面を表示します。利用者がログイン処理をおこなうと、ID Provider は、いつものように、トークンを発行し、Windows Azure Active Directory の ACS 2.0 (https://<namespace&gt;.accesscontrol.windows.net/v2/wsfederation) にリダイレクトします。
    ただし、もし、ID Provider のサイト (ドメイン) 上で、前回ログインした際に発行されたチケット (Cookie) がまだ有効なら、ログイン画面は表示されず、トークンを発行して、ACS 2.0 に戻ってくることになります。(このため、利用者から見ると、継続して使用できているように見えます。)
  3. 以降は、いつもの Passive Authentication の処理と同様です。ACS v2.0 は、トークンの妥当性を検証し、問題なければ、新たにトークンを発行して、元の Web アプリケーション (もともと利用者が要求した URL) に戻ってきます。
    そして、この Web アプリケーション (RP, Relying Party) は、再度、新しい FedAuth、FedAuth1 の Cookie (チケット) をブラウザーに発行します。

つまり、Web ブラウザーを使った一般的な Passive Authentication では、アプリケーション側で 期限切れ (Expire) の際の特別な処理を作成しておく必要はありません。(すべて、ACS と WIF が、うまくやってくれます。)
ただし、リダイレクトを想定してアプリケーションを設計しておく必要はあるので注意してください。例えば、HTTP POST の処理や、Ajax の処理の際に期限切れになった場合でも、致命的な誤動作をしないように設計やテストをおこなっておきましょう。

補足 : なお、定期的に Page を Refresh しても、新しいチケットは発行されません。(たとえ使用中であっても、一定時間が経過すると、期限切れとなります。)

補足 : Windows Live ID 認証 (OAuth2) では、ブラウザーを再起動 (いったん終了) しても、継続して処理をおこなうことができる Refresh Token と呼ばれるトークンが使用できます。Refresh Token については、「OneDrive (SkyDrive) REST API を使った Web アプリケーション開発」を参照してください。
なお、Windows Azure ACS では、これと同じトークンは提供されていません。(その先の ID Provider も対応していないといけないので、まあ、当然ですが。。。)

 

WebBrowser コントロール / Active Authentication の場合の対処方法

このため、WebBrowser コントロールを使った手法 (「WebBrowser コントロールで Windows Azure の ACS を使用した認証を行う」を参照) や、Active Authentication による手法 (「AD FS フェデレーションを処理する Client Programming (Windows Azure Active Directory 編)」を参照) では、注意が必要です。

まず、使用しているチケット (Cookie, access_token など) が期限切れになったかどうかを、クライアント アプリケーション側でちゃんと判断する必要があります。上記 1 のように空の Cookie の値を返してきている場合や、SWT (access_token を使用) の場合では有効期限に関する情報を取得できるため、 この時間を確認することで判断できます。

そして、もし、期限切れとなった場合は、上記の流れの通り、再度、認証処理をおこなって、チケット (FedAuth Cookie, access_token など) を取得しなおします。

この際、WebBrowser コントロールを使用している場合は、上記 3 に記述したように、ID Provider 側のチケットが有効な場合、そのまま自動的にログインされますが、WebBrowser コントロールが破棄されると、In-Memory のチケットも破棄されるため、毎回ログイン画面が表示されることになります。使い勝手を優先する場合は、クライアント アプリケーション側で、WebBrowser オブジェクトのライフサイクルを管理する必要があります。

また、Active Authentication の場合は、使用する ID Provider 側の Active Endpoint で、フォーム認証 Cookie などのチケットが発行されている場合は、この内容を次回から使用すると良いですが (これは、ID Provider の実装に依存します)、AD FS 2.0 の Active Endpoint などでは、これに該当するもの (Cookie など) は返していません。(もちろん、Passive Endpoint では Cookie が返ってきます。) この場合は、一定時間後、必ず、Credential (Windows Credential, User Id / Password など) を渡してログインしなおす必要があります。
Windows 認証を使う場合や、ID / パスワードの情報をクライアント側で保持する場合などには問題となりませんが、利用者にユーザー ID / パスワードの入力を促すようなクライアントの場合は、一定時間ごとに必ず入力を促す結果となり、利用者に大きなストレスとなる可能性があるので注意してください。 (例えば、ブラウザーを持たないデバイス環境で、カスタムのログイン画面と Active 認証を組み合わせて実装しているような場合です。) この場合には、ACS の管理画面 (アクセス制御サービスの管理ポータル) でトークンの期限 (Expiration) を調整しておくと良いでしょう。 (下図)

補足 : なお、AD FS 2.0 が発行するトークンは、既定で、1 時間有効なため、AD FS を使用した Active Authentication の場合には、1 時間の間、このトークンがそのまま使えます。下図の ACS の管理ポータルで、ACS 側のトークンも 1 時間 (3600 秒) に設定しておくと良いでしょう。

 

Windows Azure のトライアル (無償試用) について

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s