連載:Microsoft技術におけるアイデンティティ連携開発のいま(1)
.NETで使えるアイデンティティ連携のためのライブラリまとめ(前編)
Webアプリなどで、Facebook、Google、Twitter、企業内のActive Directoryなどの各アイデンティティ基盤と連携するための各技術(ライブラリやサービス)を、開発者視点で整理する連載スタート。
昨今、アプリケーション(以降、アプリ)のWeb化、クラウド化に伴い、Facebook、Google、Twitter、さらには企業内のActive Directoryなどの各アイデンティティ基盤との連携のニーズは高まっている。
マイクロソフトでは、こうしたニーズに対応するため、主にクラウド(Microsoft Azure(旧称:Windows Azure))で各種サービスやライブラリ群などを提供しているが、それぞれがどのような場面で使用されるかをまとめて解説している文献はあまり見かけない。そこで本連載では、現在(本執筆時点の2013年4月)、マイクロソフトで提供する(もしくは、オープンソースなどと組み合わせて使用可能な)各技術を、開発者視点で整理したい。
今回と次回はまず、アイデンティティ連携で使用可能な各技術要素(ライブラリやサービスなど)について、その位置付けを学ぶ。さらに次々回以降では、応用的ないくつかのシナリオについて、紹介した技術(ライブラリやサービス)でどのように対処できるか見ていきたい。
なお、開発言語によって使用するライブラリなどは異なるが、本連載では、サーバー側の実装基盤として.NET(プログラミング・サンプルはC#言語)を前提に記載する。
プロジェクトに含まれている、ソーシャル・アイデンティティ連携のライブラリ
まずは、オーソドックスなソーシャル・アイデンティティ(=Googleアカウント、Microsoftアカウント、Facebookのアカウントなど)の連携開発から見てみよう。
早速だが、最新のVisual Studio 2012のIDEを開き、ASP.NET MVC 4 Webアプリのプロジェクトを新規作成し、その作成過程で表示される[新しい ASP.NET MVC 4 プロジェクト]ダイアログ(下の画面)で[インターネット アプリケーション]プロジェクト・テンプレートを選択して、プロジェクトを作成してみてほしい。
プロジェクトが作成されると、次の画面のように、プロジェクトの参照ライブラリとして、「DotNetOpenAuth」と呼ばれるライブラリが挿入されているのが確認できる(このライブラリは、コア機能、アイデンティティ基盤に接続するアプリ開発の機能、ASP.NET独自の機能など、目的ごとに分かれている。詳細後述)。このDotNetOpenAuthのライブラリは、最新のASP.NET Webフォームのプロジェクトや、「ASP.NET Webサイト(Razor)」のサイトを作成しても、既定で挿入される。
プログラマーは、次回以降で紹介するさまざまなサービスやライブラリを学ぶ前に、このライブラリをちゃんと使いこなせるようにしておいたほうがよいだろう。
DotNetOpenAuthライブラリとは?
このDotNetOpenAuthは、OpenID認証やOAuth認可の流れなどを実装した.NETのプロトコル・ライブラリで、オープンソースとして提供されている。GoogleアカウントなどのOpenIDプロバイダーを使用して認証処理を実装するWebアプリ(こうした認証基盤を利用する側のアプリを、「Relying Party」と呼ぶ。単に「RP」とも表記する)をプログラミングする際に使えるだけでなく、OpenIDなどを使って認証を行うアイデンティティ・プロバイダーそのもの(=Identity Provider。単に「IdP」とも表記する。Microsoftアカウント、Googleアカウント、Facebookなど、ユーザーにログイン画面を表示し、認証を行う基盤そのもの)を構築する際にも使用できるライブラリであり、Webアプリでソーシャル・アイデンティティとの連携をシンプルに行う際に使えるライブラリだ。
上記で作成されたASP.NET MVC 4のインターネット・アプリのプロジェクトでは、このDotNetOpenAuthライブラリを、さらにASP.NET独自のライブラリにラッピングして、より扱いやすい形で実装している(後述するように、このラッピングしているライブラリの中でも、特にOAuthWebSecurityクラス(Microsoft.Web.WebPages.OAuth名前空間)は重要だ)。
【注意】Visual Studio 2013(現在、Preview版)での変更点(※2013/07/02 追記)
Visual Studio 2013(現在、Preview版を提供)から、Webプロジェクトで使用する認証処理のライブラリとして、下記のDotNetOpenAuthではなく、OWIN(Open Web Interface for .NET)が使用されている。OWIN によって、OAuth 2認可フローによる追加情報の取得や、WS-Federationを使用した認証など、さまざまな種類の認証・認可フローを統一的な方法で組み込めるようになる予定だ。
DotNetOpenAuthライブラリの基本的な使い方
例えば、DotNetOpenAuthライブラリを使ってGoogleアカウントなどの既存のアイデンティティ・プロバイダーを呼び出す場合は、通常、プログラム・コードを使ってアイデンティティ・プロバイダー独自のプロパティ設定を行い、アイデンティティ・プロバイダーへ明示的に認証を要求(=リクエスト)する。例えば、下記のようなコードだ。
using DotNetOpenAuth.AspNet.Clients; using DotNetOpenAuth.OpenId.RelyingParty; public ActionResult ToGoogle() { var idCl = new OpenIdClient("google", WellKnownProviders.Google); ……idClオブジェクトに必要な各種プロパティを設定…… idCl.RequestAuthentication(HttpContext, Request.Url); return null; } |
しかし、作成されたASP.NET MVC 4のインターネット・アプリのプロジェクトでは、このDotNetOpenAuthライブラリのOpenIdClientクラス(DotNetOpenAuth.AspNet.Clients名前空間)を直接使用せず、前述のとおり、ASP.NET独自のライブラリを使って、下記のとおりに記述すればよい。下記のコードでは、OAuthWebSecurityクラスを使って、(Global.asax.csファイルの)Application_Startメソッド内で呼び出されるAutoConfigクラスのRegisterAuth静的メソッド(=「App_Start」フォルダ内のAutoConfig.csファイル内に実装されている)の処理ブロックの中で、使用するアイデンティティ・プロバイダーを追加している(OAuthWebSecurityクラスの内部で、上記のOpenIdClientクラスが使用されている)。
using Microsoft.Web.WebPages.OAuth; public static class AuthConfig { public static void RegisterAuth() { // Microsoftアカウント OAuthWebSecurity.RegisterMicrosoftClient( clientId: "00000000330BC8C9", clientSecret: "MBlF5LGboDnq7Vds-13QjOK7z6vLfRU5"); // Googleアカウント OAuthWebSecurity.RegisterGoogleClient(); } } |
なお、上記のコードで、RegisterMicrosoftClientメソッドに指定しているclientIdパラメータとclientSecretパラメータは、「Live Connect デベロッパー センター」で事前にアプリの登録をしておき、取得する必要がある。
DotNetOpenAuthライブラリの実行例
上記のとおりに実装すると、アプリ実行時のログイン画面では、次の画面(の右側)のように、アイデンティティ・プロバイダーを選択する領域が表示される(なお、これを実現している処理は、上記のプロジェクトの「/Views/Account/_ExternalLoginsListPartial.cshtml」ファイルに記載されている)。
上の画面で、右のアイデンティティ・プロバイダー(この実行例では[Microsoft]アカウントと[Google]アカウント)のボタンをクリックすると、各プロバイダーの認証サイトにページが遷移し(=各認証プロバイダーの提供するログイン画面を表示し)、認証完了後は、このWebアプリに遷移され、認証後の処理に必要な情報が渡される。この一連の流れは、OpenIDなどで決められた仕様に従って行われる(ここでは、OpenIDやOAuthの流れの解説については省略する)。
DotNetOpenAuthライブラリの実践的な活用方法
さて、このように簡単な認証処理の追加であれば、DotNetOpenAuthライブラリそのものを扱う必要はないが、細かなカスタマイズを行う場合には、どうしてもDotNetOpenAuthライブラリを意識した実装が必要だ。
例えば、Googleアカウントのアイデンティティ・プロバイダーを使用した場合、既定では電子メール・アドレスのみが返されるが、ここに姓(Last Name)、名(First Name)などの追加のクレーム情報(または、extra data)を受け取るようにするには、下記のとおり、カスタムのOpenIdClientクラスを作成する必要がある。これまでプログラム・コードで使用しなかった(OAuthWebSecurityクラスの内部で扱われていた)DotNetOpenAuthライブラリのクラスを扱う必要があるのだ。
下記のコードに示すカスタムのOpenIdClientクラス(この例では「MyGoogleClient」クラス)では、Googleアカウントに姓(Last Name)、名(First Name)を要求する処理(=下記のコードにおけるOnBeforeSendingAuthenticationRequestメソッド)と、Googleアカウントから返されるこれらの値を抽出する処理(=下記のコードにおけるGetExtraDataメソッド)を実装している。
using DotNetOpenAuth.AspNet.Clients; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; using Microsoft.Web.WebPages.OAuth; using System.Collections.Generic; public static class AuthConfig { public static void RegisterAuth() { ……省略…… // カスタムのOpenIdClientである「MyGoogleClient」を登録 //OAuthWebSecurity.RegisterGoogleClient(); OAuthWebSecurity.RegisterClient(new MyGoogleClient(), "Google", null); } } public class MyGoogleClient : OpenIdClient { public MyGoogleClient() : base("google", WellKnownProviders.Google) { } protected override void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) { var fetchReq = new FetchRequest(); fetchReq.Attributes.AddRequired(WellKnownAttributes.Contact.Email); fetchReq.Attributes.AddRequired(WellKnownAttributes.Name.First); fetchReq.Attributes.AddRequired(WellKnownAttributes.Name.Last); request.AddExtension(fetchReq); } protected override Dictionary<string, string> GetExtraData(IAuthenticationResponse response) { FetchResponse fetchRes = response.GetExtension<FetchResponse>(); var extraDat = new Dictionary<string, string>(); extraDat.Add("email", fetchRes.GetAttributeValue(WellKnownAttributes.Contact.Email)); extraDat.Add("firstName", fetchRes.GetAttributeValue(WellKnownAttributes.Name.First)); extraDat.Add("lastName", fetchRes.GetAttributeValue(WellKnownAttributes.Name.Last)); return extraDat; } } |
なお、追加したクレーム(extra data)は、下記のコードのようにしてWebアプリから取得できる。
using DotNetOpenAuth.AspNet; using Microsoft.Web.WebPages.OAuth; [AllowAnonymous] public ActionResult ExternalLoginCallback(string returnUrl) { AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action( "ExternalLoginCallback", new { ReturnUrl = returnUrl })); // Extraデータ(姓、名など)の取得テスト IDictionary<string, string> extraData = result.ExtraData; foreach (var key in extraData.Keys) { string item = extraData[key]; ……省略…… } ……省略…… } |
アイデンティティ・プロバイダーから返ってきた後の処理は、OpenID、OAuthなどに関係なくWebアプリ側(今回の場合、作成したASP.NET MVCアプリ側)の仕事となる。この処理は、ASP.NET MVC 4の既定のプロジェクトの場合(=[インターネット アプリケーション]のプロジェクト・テンプレートを選択した場合)、下記のコード(=AccountControllerクラスの実装コード)のようになっている。
[AllowAnonymous] public ActionResult ExternalLoginCallback(string returnUrl) { AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action( "ExternalLoginCallback", new { ReturnUrl = returnUrl })); if (!result.IsSuccessful) { return RedirectToAction("ExternalLoginFailure"); } if (OAuthWebSecurity.Login( result.Provider, result.ProviderUserId, createPersistentCookie: false)) { return RedirectToLocal(returnUrl); } ……省略…… } |
上記のコードでは、OAuthWebSecurity.Loginメソッドを呼び出し、この中で、ASP.NETのフォーム認証(=FormsAuthenticationクラス)の仕組みを使って認証情報(=認証チケット)をHTTPのクッキー(Cookie)に書き込んでいる。もちろん、プログラマー自身が、フォーム認証(FormsAuthentication)クラスを使って必要な認証チケットを書き込んでもよいだろう。
この処理が実行されて以降、このASP.NET MVCアプリは、書き込まれた認証チケットの内容を見て認可の処理などを実装できる(なお、実際のクッキーの書き込みは、OAuthWebSecurity.Loginメソッドが実行されたページの表示時となるため、書き込まれた認証情報がサーバー側のコードで利用できるようになるのは、その次に表示されるページ以降となるので注意してほしい)。
既定のプロジェクトが生成するコードに関する注意点
なお、ASP.NET MVC 4の既定のプロジェクト(=標準のプロジェクト・テンプレートから作成したプロジェクト)では、メンバーシップ・データベースも使用されている点に注意してほしい(前掲のログイン画面で、左ペインの[ユーザー名]と[パスワード]を入力する部分がこれに該当する。もちろん、不要であれば、このメンバーシップ・データベースを使用した処理の箇所は全て削除して構わない)。例えばクラウド上に配置する場合は、データベース接続文字列(=Web.configファイルに記述されている)も変更する必要があるだろう。
ただし、最新のメンバーシップ・データベースは、Entity Framework(のコード・ファースト)を使ってクラス構成(例えばユーザー情報など)をデータベースに反映したシンプルなものだ。かつてのSQL Serverメンバーシップ・プロバイダーを使用したデータベースのようにストアド・プロシージャなども使用されておらず、単に接続先を「SQLデータベース」(=Azure上のリレーショナル・データベース)などに変更するだけで容易にクラウド環境に対応可能だ(なお、作成されるいくつかのテーブルについては、WebMatrix.WebData.dllファイル(=WebMatrix.WebDataアセンブリ)の中でクラス定義されており、プログラマーからは直接見えない)。
■
今回は、準備として、オーソドックスなソーシャル・アイデンティティ連携で使えるDotNetOpenAuthライブラリについて説明した。.NET用のFacebook SDK、Live SDKなど、アプリ専用のSDKを使用しても特定のアイデンティティ・プロバイダーとのフェデレーション(=連携)は可能だが、未知のアイデンティティ・プロバイダー(例えばカスタムのOpenIDプロバイダーなど)も含めた複数のソーシャル・アイデンティティを対象に連携を行う場合には、このDotNetOpenAuthライブラリは大変使い勝手がよいだろう。
次回は引き続き、ここで取り上げなかった多くの課題を解決するためのAzure上のサービスやライブラリを紹介したい。
1. 【現在、表示中】≫ .NETで使えるアイデンティティ連携のためのライブラリまとめ(前編)
Webアプリなどで、Facebook、Google、Twitter、企業内のActive Directoryなどの各アイデンティティ基盤と連携するための各技術(ライブラリやサービス)を、開発者視点で整理する連載スタート。
2. .NETで使えるアイデンティティ連携のためのライブラリまとめ(後編)
アイデンティティ連携で使用可能なライブラリやサービスなどをまとめる記事の後編。今回はAzure Active Directoryのアイデンティティ連携を中心に解説。
3. カスタム・アプリケーションによる認証フローとプログラミング
ネイティブ・アプリのプログラム・コードから認証を行う方法とは? Azure Active Directoryを例に、OAuth 2.0をベースにした、プラットフォームに依存しない新しい手法を考察する。
4. Azureの認証におけるその他サービス ~ Azureモバイルサービス、多要素認証
最終回。Azureモバイルサービスや、多要素認証など、これまでの連載で取り上げなかった、認証に関わる先進的な技術を簡単に紹介する。