ASP.NET Identity を使って Microsoft アカウントで認証する
進捗ダメです。
などと一部の方に状況報告しつつ、ASP.NET Identity を使ってみようシリーズその4です。
その1 - ASP.NET Identity のセキュリティスタンプ機能を使う
その2 - ASP.NET Identity で二要素認証を使う - SMS 編
その3 - ASP.NET Identity で二要素認証を使う - E-mail 編
今回やること
今回は External Login を試してみます。
サービスプロバイダは Microsoft アカウントを使いますが、Twitter でも Facebook でも変わらないと思いますので、適宜読み替えて下さい。
前提
いつも通り環境は Visual Studio 2013 Update 3 です。
ASP.NET MVC Web アプリケーションテンプレートからプロジェクトを作成しておいてください。
Microsoft アカウントでの認証の流れ
以上が大まかな流れです。
Microsoft アカウントで連携するアプリケーションの登録
そもそもどこで登録すれば良いか分からなくて、これが一番時間かかりました。
https://account.live.com/developers/applications/index
↑ のページから「アプリケーションの作成」を行ってください。
アプリケーション設定を作り終えたら、画面左のメニューの「API 設定」を開いてリダイレクト先の URL を登録します。
URL のドメインは適当にオリジナルに設定して下さい。
はっきりしていませんが、どうやら localhost では登録を受け付けてくれないようです。
また、URL の末尾に signin-microsoft
という文字列を追加します。
上記設定が完了したら、「アプリケーション設定」メニューを開きます。
クライアント ID とクライアントシークレットが確認出来ますのでメモっておいてください。連携の時に使います。
OWIN の Microsoft アカウント認証機能を有効化
アプリケーションで Microsoft アカウント認証機能を有効化します。
APP_Start\Startup.Auth.cs
の以下の箇所を修正します。
// APP_Start\Startup.Auth.cs // 以下の行のコメントアウトを解除して、先ほどメモっておいたクライアント ID とシークレットをセット app.UseMicrosoftAccountAuthentication( clientId: "your_client_id", clientSecret: "your_client_secret");
UseMicrosoftAccountAuthentication
メソッドは、Microsoft.Owin.Security.MicrosoftAccount
名前空間内に定義された IAppBuilder
に対する拡張メソッドです。
実態は MicrosoftAccountAuthenticationMiddleware
というミドルウェアですね。こちら でソースコードが読めます。
そして認証処理そのもののは MicrosoftAccountAuthenticationHandler
で行われているようです。OAuth v2 を使っているようですが、気になる方は ソースコード をどうぞ。
(テストのため) IIS Express の設定
ここまででアプリケーションの設定としては完了です。この後は、テストのために IIS Express の設定を行います。
連携アプリケーションの登録の時に、リダイレクト先 URL に localhost でないドメインを設定したので、その URL でアプリケーションが見れるよう OS や IIS を設定します。
IIS Express で仮想サイトに複数のホスト名を割り当てる - しばやん雑記 を参考にさせていただきました。
C:\Users\<user name>\Documents\IISExpress\config\applicationhost.config
を以下の通り編集します。
<site name="your_application_name" id="7"> <application path="/" applicationPool="Clr4IntegratedAppPool"> <virtualDirectory path="/" physicalPath="c:\users\<user name>\documents\visual studio 2013\Projects\WebApplication5\WebApplication5" /> </application> <bindings> <binding protocol="http" bindingInformation="*:61548:localhost" /> <!-- ↓ の行を追加 --> <binding protocol="http" bindingInformation="*:61548:<test domain>.com" /> </bindings> </site>
続いて、プロジェクトのプロパティを開き、プロジェクトの URL を変更します。
最後に hosts ファイルを編集します。
# localhost name resolution is handled within DNS itself. # 127.0.0.1 localhost # ::1 localhost # ↓ の行を追加 127.0.0.1 <your domain>
実行する
ここまでで全ての準備は完了です。
アプリケーションを実行してログインしようとすると、以下のようになっているはずです。
「別のサービスを利用してログインしてください。」の下に「Microsoft」というリンクがあります。
これを押すと Microsoft アカウントのログイン画面が表示され、Microsoft アカウントにログインすると同時にアプリケーションのログインも完了します。簡単ですね。
よく分からないんだけど
あまりに簡単すぎてどう処理が流れていったのか掴みにくいと思いますので、簡単に流れでも(本当に簡単ですが)。
ログイン画面の「Microsoft」リンクを押下するというユーザー操作から、、、
Views\Account\_ExternalLoginsListPartial.cshtml
から/Account/ExternalLogin
アクションへExternalLogin
アクションメソッドが、ChallangeResult
を返すHttpUnauthorizedResult
を継承したActionResult
アプリ独自のクラスChallangeResult
メソッド内で、OWIN に認証処理を委譲
- Microsoft サイトから
/Account/ExternalLoginCallback
にリダイレクト /Account/ExternalLoginCallback
アクション中で認証SignInManager<TUser, TKey>
クラスのExternalSignInAsync
メソッドにより認証
大分見難いですね、、、すいません。
SignInManager<TUser, TKey>
クラスは、 Microsoft.AspNet.Identity.Owin
名前空間内に定義された、ASP.NET Identity のログイン処理を一括で見るサービスです。OWIN とがっつり連携し、Identity を利用する上である程度の複雑さを担ってくれています。
また、データは、アプリケーションのアカウント情報は普通にログインした時と同じく AspNetUsers
テーブルに保存され、Microsoft アカウントとのひも付きは AspNetUserLogins
テーブルに保存されるようです。