ラベル MVC の投稿を表示しています。 すべての投稿を表示
ラベル MVC の投稿を表示しています。 すべての投稿を表示

2015年8月3日月曜日

[Azure AD/ASP.NET]ユーザ属性を取得する2つの方法


こんにちは、富士榮です。

7/29のWindows10のリリースで盛り上がっていますが、その直前にひそかにリリースされていたVisual Studio 2015ではASP.NETのアイデンティティ関連機能が色々と拡張されています。

概要はVisual Studioの公式blogでアナウンスされているので、そこはそちらに任せておくとして、今回はASP.NET MVC5のプロジェクト・テンプレートが拡張されてGraph APIを使ってAzure ADのユーザ属性の取得がされるように変わっているのでその辺りの解説をしたいと思います。また、以前のバージョンから仕えましたが、SSO時のJWT(JSON Web Token)からClaim(属性)を取り出す方法について解説します。

 参考)Visual Studioの公式blog
  Identity Management Features in Visual Studio 2015
  http://blogs.msdn.com/b/visualstudio/archive/2015/07/22/identity-management-features-in-visual-studio-2015.aspx


◆ASP.NETでAzure ADからユーザ情報を取得する方法

先にも書きましたが、ASP.NETでAzure ADと連携するアプリケーションを開発する場合、以下の2つの方法で認証済みユーザの属性を取得することができます。

1.認証時にAzure ADで発行されるJWTに含まれるClaim(属性)を取得する
2.認証後、Graph APIを使ってディレクトリ(Azure AD)上のユーザ属性を取得する


早速それぞれの方法について解説します。


◆JWTに含まれるClaimを取得する

ASP.NETアプリケーションのプロジェクトを作成する際、認証の構成を設定できます。



ここでAzure ADのテナント情報を入れるとアプリケーション起動時にAzure ADを使って認証が行われるようになります。
その際、内部的な動作としてはOpenID Connectを使ったID連携が行われ、Azure ADからアプリケーションにJWTがPOSTされてきます。

POSTされるid_tokenの中身をJWT Decoderでデコードしてみると、以下のようなClaimが含まれていることがわかります。

{
  "aud": "0897xxxxxxxxx65c",
  "iss": "https://sts.windows.net/2c6xxxxxxxxxxxx1bfff/",
  "iat": 1438609784,
  "nbf": 1438609784,
  "exp": 1438613684,
  "ver": "1.0",
  "tid": "2c62f1axxxxxxxxxxxbb1bfff",
  "oid": "457ca53xxxxxxxxxe363dc73c",
  "upn": "nfujie@xxxxxxxxx.onmicrosoft.com",
  "sub": "ILvM1kZdv7kxxxxxxxxiPrw2fPusCk",
  "given_name": "Naohiro",
  "family_name": "Fujie",
  "name": "Naohiro Fujie",
  "amr": [
    "pwd"
  ],
  "unique_name": "nfujie@xxxxxxxx.onmicrosoft.com",
  "nonce": "63574206878.....snip....LTg0YmMtOGFkYmMyZTcwY2Yz",
  "c_hash": "QIsD2...snip...fYgA"
}


これを見るとユーザのUPN(userPrincipalName)や姓(surName)、名(giveName)などもid_tokenの中に含まれていることがわかります。
これらの属性をアプリケーションから取得することが出来れば、アプリケーション上でログインIDだけでなく、ユーザ表示名を表示してあげることが出来るようになるはずです。

では、早速取得してみます。
まず、Azure ADを使った認証がプロジェクト・テンプレート上でどのように実装されているのかを見てみます。
ソリューション・エクスプローラからApp_Startフォルダの中のStartup.Auth.csを開くと、Microsoft.Own.Security.OpenIdConnectを使ってAzure ADとのOpenID ConnectでのID連携を実装していることがわかります。


と、いうことは認証後、id_tokenに関する情報はOwinContextに入れられるはずなので、アプリケーションからはOwinContextの中身を検索することでClaim情報が取得できるはずです。

RequestのGetOwinContext()メソッド使ってContextを取得し、その中の認証およびユーザに関する情報をAuthenticationプロパティ/Authentication.Userプロパティから取得します。
あとは、取得したUserオブジェクトのClaimsコレクションからClaimを順番に取り出せばid_tokenの中身が取得できます。

具体的には以下のようなコードを書きます。

var ctx = Request.GetOwinContext();
var user = ctx.Authentication.User;
var response = ctx.Response;
response.ContentType = "text/html";
if (user.Identity.IsAuthenticated){
   foreach(var claim in user.Claims){
      response.Write(claim.Type + "=" + claim.Value + "<BR>");
   }
}




◆Graph APIを使ってAzure ADから属性を取得する

次はGraph APIを使って認証済みユーザの属性をAzure ADへ問い合わせ、取得する方法です。
プロジェクトの認証構成を行う際に、ディレクトリ情報の読み取り許可を与えることでGraph APIを使ってユーザ情報を取得できるようにプロジェクトが構成されます。


アプリケーションを起動し、Azure ADで認証後、画面右上に表示されるログインIDをクリックするとUserProfileが表示されます。



この部分の実装を見るとGraph APIを使ってユーザ属性を取得しています。
対象のソースはControllers以下のUserProfileControllers.csです。GraphClientが使用されていることがわかります。



実際はこのControllerから呼び出されるViewにuserオブジェクトを渡しているので、表示項目の見せ方については対象のViewであるViews/UserProfile/Index.cshtmlを見てみます。ここでは@Model.[属性名]という形で属性を取得してテーブルに埋め込んでいますので、好きな属性を指定してテーブルを拡張していくことで任意の属性を表示させることが可能です。(今回はJobTitle属性を追加しています)




どちらの方法が適しているのかは、どんな属性が必要なのかをベースに考えれば良いと思います。例えば役職や組織情報を使ってアクセス権制御を行いたければGraph APIを使う方法になると思いますし、単に名前を表示させるだけならJWTから取得する方が通信量が少ないので実装としては軽くなります。
※現状のAzure ADではid_tokenに含めるClaimのカスタマイズができないので、id_tokenにない属性を取得したければGraph APIを使うしか方法がありません。


いずれにしてもAzure ADを使った認証や属性取得がかなり楽に実装できるようになっていますので、あまりカスタムで頑張った実装をするよりもテンプレートにある仕組みを使ってアプリケーション開発をしていった方が今後はよさそうですね。

2015年6月20日土曜日

[IdM全般]トレーニングコンテンツ色々/プロジェクトの進め方~モバイルデバイス管理~開発まで

最近のポストで2回ほど紹介したMicrosoft Virtual Academy(MVA)というオンライントレーニングコースですが、その後もアイデンティティ関連のコースを探索していたら何個か面白いものが出てきたので紹介したいと思います。

参考)これまで紹介したポスト
[IdM全般]アイデンティティ管理プロジェクトに必要なスキル(Active Directory/Azure AD編)
[AzureAD]入門コンテンツ - クラウド時代のActive Directory次の一手シリーズ



今回紹介させて頂くコンテンツの一つ目は「ID とアクセス管理の全体像」シリーズです。

基本はMicrosoft Conference 2014の中のセキュリティ~ID管理系のコンテンツを集めたシリーズになっており、以下の6つのコンテンツ+セットアップ手順書のセットになっています。
  • 基本から見直すセキュリティ~標的型攻撃の実態と取り組むべきセキュリティ対策~
  • Dynamic Identity Framework~クラウド時代適応のためのID管理手法~
  • ハイブリッドな認証基盤で生産性を高めるために必要な基礎知識
  • モバイルの企業活用を支えるデバイス統合管理ソリューション
  • Azure Rights Managementによる社外ユーザーとのセキュアのコンテンツ共有の実現
  • 多要素認証Deep Dive~ハイブリッド認証基盤だからこそ実現できる柔軟で高機能な多要素認証~

特に2つ目のDynamic Identity Framework(DIF)のセッションでは実際のコンサルティングプロジェクトで企業のID管理の現状分析と課題の洗い出しを行う方法論について語られているのでプロジェクトにかかわる方には参考になるかもしれません。

もちろんそのような方には、JNSAのアイデンティティ管理WGの出している「改訂版クラウド環境におけるアイデンティティ管理ガイドライン」もあわせておすすめです。(宣伝)



二つ目に紹介するMVAコンテンツはAndroid / iOSのようなモバイルデバイスを管理するためのソリューションセット「Enterprise Mobility Suite(EMS)」に関する「Taming Android and iOS with Enterprise Mobility Suite」というコンテンツです。
URL:http://goo.gl/8IOhcm

基礎的な部分からAndroid / iOSそれぞれについての具体的な仕組みや設定についてデモを交えて紹介しています。


最後は開発系コンテンツの「Customizing ASP.NET Authentication with Identity」です。
URL:http://goo.gl/t95rEu

OAuth/ソーシャルアイデンティティ連携から多要素認証まで、ASP.NET Identityでどうやって実装するのか、具体的な実装方法に関する紹介をしています。


私を含めBlogやTechnet / MSDNなどだと都度都度情報が分散してしまっているので、こういう形でまとめてあると基礎から勉強しなおすにはいいですね。


2014年5月21日水曜日

[AAD/ASP.NET] (続)OpenID Connectを使ってAADでログオンする~response_mode=fragment編

先日のポストの続きです。

前回はOWIN Security MiddlewareのOpenID Connectを使ってAzure Active Directory(AAD)でのログオンを行いました。
今回も基本的にやることは同じなのですが、OWINのOpenID Connectのresponse_modeの初期値がform_postなので、一般的なOpenID ConnectをサポートしたIdentity Providerへの流用の可能性を考えるために、Implicitフローで使われるfragmentを使ってid_tokenを受け渡す場合の工夫について試してみます。
※尚、現状AADではImplicitフローをサポートしているという表明があるわけではないので、今回紹介するのはあくまでImplicitもどきです。


■処理の流れとAADの場合
まず、OpenID ConnectにおけるImplicit Clientではどのような流れでid_tokenが発行されるのか?、AADではどうなるのか?についてみておきたいと思います。
 参考)OpenID Connect Implicit Client Implementer's Guide 1.0 - draft 15の日本語訳
    http://openid-foundation-japan.github.io/openid-connect-implicit-1_0.ja.html

大まかな流れは、以下のようになっています。

①Client は必要なリクエストパラメータを含んだ Authentication Request を構築する.
②Client は Authorization Server にリクエストを送信する.
③Authorization Server は End-User を認証する.
④Authorization Server は End-User の Consent/Authorization を取得する.
⑤Authorization Server は End-User を ID Token, およびもし要求されていれば Access Token とともに, Client に戻す.
⑥Client はそれらのトークンを検証し, End-User の Subject Identifier を取得する.


具体的には以下のような通信が行われます。

①~②クライアントからのAuthorizationリクエスト
https://server.example.com/authorize?
    response_type=id_token%20token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj


response_typeにid_tokenおよびtokenを付けて要求を投げる必要がある(REQUIRED)、というのが仕様です。
しかし、現状でAADはresponse_typeにtokenをサポートしていないので、id_tokenだけを要求することにします。また、前述の通り、AADではresponse_modeの初期値がform_postなので、Implicit(もどき)の場合はresponse_mode=fragmentをつける必要があります。

結果、以下のようなリクエストになります。
https://login.windows.net/{tenantid}/oauth2/authorize?
    response_type=id_token
    &response_mode=fragment
    &client_id=xxxxx
    &redirect_uri=https%3a%2f%2flocalhost%3a44307%2fAccount%2fFragment%2f
    &scope=openid+profile
    &state=yyyyy
    &nonce=zzzzz



③~④End-Userの認証、同意取得
この部分は仕様のスコープ外なので手段は問いません。
AADではws-federationを使ってhttps://login.microsoftonline.comへ認証要求を投げ、ユーザ認証を行います。
https://login.microsoftonline.com/login.srf?
    wa=wsignin1.0
    &wtrealm=https%3a%2f%2flogin.windows.net%2f
    &wreply=https%3a%2f%2flogin.windows.net%2f{tenantid}%2fwsfederation
    &wctx=xxxx
    &wp=MBI_FED_SSL
    &id=


認証が成功するとhttps://login.windows.net/{tenantid}/wsfederationに対してSAMLトークンがPOSTされ、認証結果およびユーザ情報が渡されます。


⑤id_tokenをクライアントへ返す
HTTP302でredirect_uriへ戻します。その際、フラグメント(#)にid_tokenなど要求されたトークンを付加します。
HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    access_token=SlAV32hkKG
    &token_type=bearer
    &id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
    &expires_in=3600
    &state=af0ifjsldkj


AADの場合は、先ほどのリクエストでtokenを要求できませんでしたので、id_tokenのみが返ってきます。
HTTP/1.1 302 Found
  Location: https://localhost:44307/Account/Fragment/#
    id_token=eyJ0....
    &state=yyyyy
    &session_state=zzzzz



⑥返ってきたid_tokenを検証する
id_tokenがフラグメントで返ってきますので、UserAgent(ブラウザ等)上でパラメータを解析してクライアントへ送ってあげる必要があります。通常はJavaScriptでlocation.hashを解析してクライアントへid_tokenなどをPOSTしてあげます。
今回もredirect_uriに指定したページ(https://localhost:44307/Account/Fragment/)へのGETリクエストすると以下のようなJavaScriptを含むHTMLを返すようにしています。(テストなのでベタ書きしています)
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title></title>
</head>
<body>
    <form method="post" name="autopost" action="https://localhost:44307/">
        <script type="text/javascript">
            var params = location.hash.substring(1).split('&');
            var id_token = params[0].substring(9);
            var state = params[1].substring(6);
            var session_state = params[2].substring(14);

            document.write("<input type=hidden name=id_token value=");
            document.write(id_token);
            document.write(" />");
            document.write("<input type=hidden name=state value=");
            document.write(state);
            document.write(" />");
            document.write("<input type=hidden name=session_state value=");
            document.write(session_state);
            document.write(" />");
        </script>
        <input type="submit" value="Submit" />
    </form>
    <script language="javascript">window.setTimeout('document.forms[0].submit()', 0);</script>
</body>
</html>




結果、フラグメントでわたってきたid_tokenがOWINのOpenID Connect Middlewareが動いているASP.NETアプリケーション(https://localhost:44307)へPOSTされ、自動的にトークン検証~ユーザ情報の取り出しを行ってくれます。


ここまでのフローをざっとシーケンスにしたものが以下の図です。



■ASP.NET/OWINでの実装
デフォルトのASP.NET/OWIN Middlewareではフラグメントでわたってきたid_tokenをUserAgent側で解析してPOSTする部分が用意されていないので、その部分だけは作ってあげる必要があります。
具体的にはViewを一つ用意して、そのエンドポイントに対するGETがあった場合に先のJavaScriptを含むHTMLを返すようにします。

以下の手順で実装しました。

ソリューション・エクスプローラからAccount Controllerへ新規MVC5 Viewを追加します。先のシーケンスの中にも出てきたように、今回はエンドポイントの名前を「Fragment」としています。



新規作成されたfragment.chtmlに先のJavaScriptを含むHTMLを記載します。



次に、Account Controllerにアクションを定義します。AccountController.csに以下のコードを追記します。
[AllowAnonymous]
public ActionResult Fragment()
{
    return View();
}



また、OWINの認証設定部分(Startup.Auth.cs)に以下の設定を入れます。
・response_type:id_token
・response_mode:fragmentを指定
・redirect_uri:先に追加したView(Fragment)のエンドポイントを指定

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions()
    {
        Client_Id = "xxxxx",
        Authority = "https://login.windows.net/{tenant}.onmicrosoft.com",
        Response_Type = "id_token",
        Response_Mode = "fragment",
        Redirect_Uri = "https://localhost:44307/Account/Fragment/",
        Description = new Microsoft.Owin.Security.AuthenticationDescription()
        {
            Caption = "Azure Active Directory",
            AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType
        }
    });



これで実行すると前回と同じような動きに見えますが、裏側ではImplicit(もどき)でid_tokenが受け渡されます。

2013年10月26日土曜日

[WAAD]OAuth で WebAPI を保護する ③

前回、前々回に引き続き Windows Azure Active Directory(WAAD)の OAuth 2.0 で WebAPI を保護する方法を紹介します。

これまでのポスト
 [WAAD]OAuth で WebAPI を保護する ①
 [WAAD]OAuth で WebAPI を保護する ②


前回までで環境は整ったので、今回は実際にアクセスしてみます。(今回でようやく終わりです)

◆作業の流れ
これまでの作業の流れは以下の通りです。今回は最後の 7 を実行します。


  1. WebAPI の作成:今回は ASP.NET MVC4 の WebAPI を使います
  2. WebAPI の保護:WAAD を使って認可する様に設定を行います
  3. WebAPI を WAAD に登録:WAAD の保護対象リソースとして WAAD へ登録します
  4. OAuth クライアントの作成:本来は真面目にクライアントも作るのですが、今回は生の動きを見るために Chrome Extension の Advanced REST Client とダミー URL を使います
  5. OAuth クライアントを WAAD に登録:WAAD を使うアプリケーションとして OAuth クライアントを登録します
  6. WebAPI へのアクセス許可設定:OAuth クライアントが WebAPI へアクセスできるように設定します
  7. 動作確認:実際に OAuth2.0 のフローに従ってアクセスできるかどうかテストします。(今回は認可コードフローを試してみます)



◆実際の作業

7.動作確認

実際に OAuth クライアントから WebAPI へアクセスします。OAuth の認可コードフローを使って WAAD からアクセスに必要なアクセストークンを取得するので、まずは OAuth クライアントの client_id と client_secret を確認します。
クライアント ID(client_id)は 管理ポータルのアプリケーションの構成の中にありますが、client_secret は初期状態では生成されていません。そこでキーの項目で有効期限を選んで生成をします。尚、作成後ページ遷移をするとそのキーは二度と参照できなくなるので、必ずコピーしておきます。万一忘れてしまった場合は再度キーを生成します。




これで実際にアクセスするための準備はすべて終了です。
もう一度おさらいですが、今回やりたいことをシーケンスに表わすと以下のような流れになります。



上記のシーケンスの通り、まずは WAAD の 認可エンドポイントへリクエストを投げます。

※今回はクライアントを作らずにブラウザと Chrome Extension の Advanced REST Client を使うので、リソースオーナー(ユーザ)がクライアントへアクセスしてきたと仮定して、クライアントがリソースオーナーへリダイレクトしてくる認可要求を手動で実行します。

投げるリクエストは以下の通りです。

・メソッド:GET
・エンドポイント:
 https://login.windows.net/common/oauth2/authorize?api-version=1.0
・パラメータ
 response_type : code
 client_id : 先に取得した Client の client_id

実際はブラウザから以下の URL へアクセスします。
 https://login.windows.net/common/oauth2/authorize?api-version=1.0&response_type=code&client_id=[client_id]


すると、WAAD の認可エンドポイントから認証要求が返ってきますので、WAAD 上に登録した組織のアカウントでログインします。(フローの①)


認証が通ると、再度認可エンドポイントへ遷移し、設定がうまくいっていれば認可コードが払い出されます。
クライアントがダミー(WAAD に登録したアドレスが適当に http://localhost)なので、ブラウザにはエラーが表示されますが、アドレスバーを見るとちゃんとコードがパラメータに入っていることがわかります。
これが上記フローの②に該当します。


これで認可コードが取得できたので、次は WAAD のトークンエンドポイントで認可コードとアクセストークンを交換してもらいます。
今度は POST メソッドを使うので Advanced REST Client を使います。

投げるリクエストは以下の通りです。

・メソッド:POST
・エンドポイント:
 https://login.windows.net/common/oauth2/token
・フォームデータ
 grant_type : authorization_code
 client_id : 先に取得した Client の client_id
 client_secret : 先に取得した Client の client_secret
 code : 取得したcode
 resource : WebAPI の URI(WAAD に登録した URI)


こんな感じで投げます。


うまくいけば HTTP 200 が返ってきて、結果にアクセストークンが返ってきます。フローの④の部分です。(ついでに id_token も返ってきてます)


ようやくこれで WebAPI へアクセスする準備が整いました。
あとは単純に、このアクセストークンを Authorization ヘッダにセットして WebAPI の URI へリクエストを投げるだけです。

投げるリクエストは以下の通りです。実際のアクセストークンの前に「Bearer 」を入れるのを忘れないでください。

・メソッド:GET
・エンドポイント:
 http://localhost:52941/Api/Values
・ヘッダ
 Authorization : Bearer [取得したアクセストークン]

こんな感じです。上記フローの⑤に当たります。


前々回で保護設定をした状態では HTTP 401 が返ってきていましたが、今回はちゃんと HTTP 200 が返ってきます。
データも取得できているようです。



いかがでしょうか?
概念的に OAuth2.0 を使ってリソースを保護する、と言うだけなら簡単なのですが、実際にステップ毎に実行してみると理解ができると思います。
また、Visual Studio 2013 からは OWIN という新しい認証の実装が入ってきていますが、内部的にはこんな感じで動いています(たぶん)。

参考)Understanding OWIN Forms authentication in MVC 5




2012年11月4日日曜日

VS2012 用の Identity and Access Tool が RTM


遅ればせながら 10月23日にリリースされた Visual Studio 2012 用の Windows Identity Foundation Tools を試してみます。

まず、機能面の紹介です。
基本的には以前の WIF の Federation Utility と変わりませんが、個人的には下記が大きなポイントだと思います。

1.Identity Provider を ローカル STS、ビジネス Identity Provider(AD FS2.0)、Windows Azure Access Control Service から選択できるようになった。
  ⇒以前は、新しい STS を作成するか、既存の STS を利用するかの選択だった。

2.管理者として Visual Studio を実行しなくても Identity and Access Tool が利用できるようになった。
  ⇒以前は管理者として Visual Studio を実行しないと Federation Utility が実行できなかった。

3.ACS 側の設定を自動的に作成してくれるようになった。
  ⇒以前は ACS 上に RP の作成およびクレーム・ルールの作成を手動で行う必要があった。

4.認証されていないリクエストに対するアクションを選択できるようになった。
  ⇒以前は単純に STS にリダイレクトするだけだったが、今回から加えて controller を生成することが出来るようになった。


特に3番目、4番目については開発者にとって非常に有用な機能なのではないでしょうか?


では、早速試してみます。

■モジュールのダウンロードとインストール
 モジュールは vsix 形式で提供されていますので、ダウンロード、実行すると Visual Studio の拡張機能が有効になります。

 Identity and Access Tool のダウンロード URL
  http://visualstudiogallery.msdn.microsoft.com/e21bf653-dfe1-4d81-b3d3-795cb104066e


■プロジェクトの作成
 Controller の自動生成を試してみたいので、今回は MVC4 のプロジェクトを作ってみます。もちろん Visual Studio は管理者で実行しなくても大丈夫です。

 テンプレートから web -> ASP.NET MVC 4 Web アプリケーションを選択し、適当な名前を付けてプロジェクトを作成します。


 OK をクリックするとプロジェクト テンプレートの選択画面が出てきますが、デフォルトで選択されている[インターネット アプリケーション]を選んだまま OK をクリックします。



■Identity and Access Tool の設定
 プロジェクトの作成が終わったら、ソリューションエクスプローラからプロジェクト名を右クリックして表示される[Identity and Access]を開きます。


 Choose where your users are from でどの STS を使うのか選択できます。今回は ACS の自動設定を試してみたいので、[Use the Windows Azure Access Control Service]を選択します。
 すると、Select one or more providers from the ones configured in the ACS Namespace: で使用する ACS の Namespace の設定を行うリンクが表示されるので、クリックします。


 Configure ACS namespace のダイアログが表示されるので、ACS namespace および management key を入力します。


 ここで設定する management key は ACS の管理ポータルの管理サービスのパスワードです。



 設定が完了し、ダイアログを閉じると ACS 上に設定されている IdP 一覧が取得されて表示されるので、このアプリケーションで利用したい IdP を選択し、一旦 OK をクリックし Identity and Access Tool を閉じます。


 ちなみに、このとき ACS 管理ポータルを見ると 証明書利用者アプリケーションとして作成したアプリケーションが登録されていることがわかります。


 同様に規則グループも自動生成されます。内容は単なるパススルーなので、必要に応じて編集をしてあげる必要はあります。



■Controller の自動生成
 次は、これまた新機能である Controller の自動生成を試します。
 再び Identity and Access Tool を起動し、今度は[Configuration]タブを開きます。
 すると、Choose how to handle unauthenticated requests という項目があるので、[Generate a controller in your project to handle the authentication experience at the following address]を選択します。


 これで、認証されていないリクエストに対応する Controller が生成されましたので、実際に認証が必要なリクエストを行うように設定を行います。
 今回はデフォルトの About 画面を認証が必要な画面として定義してみます。
 方法は簡単で、HomeController.cs の About() に対して [Authorize] を追加するだけです。



■アプリケーションの実行
 では、F5 キーを押して実際にアプリケーションを実行してみます。

 起動してきたら[バージョン情報]をクリックします。


 すると、ログインページが表示されます。ホームレルム ディスカバリ先として、先ほど ACS から取得してきた IdP 一覧が表示されるのがわかります。


 今回は Google を選択してみます。Google アカウントへリダイレクトされ、Account Chooser が表示されるので、使いたいアカウントをクリックします。



 認証が終わると、ホーム画面へ戻り、ユーザ名が取得できているのがわかります。




いかがだったでしょうか?非常に単純なサンプルだったので実際は色々とカスタマイズが必要にはなるでしょうが、ほぼノンコードでここまで出来るようになっている、という意味で以前のツールに比べてもかなりの進化を遂げていることがわかります。
ACS を使って多くの外部 IdP ユーザを対象にしたアプリケーションを簡単に開発できるので、EC サイトなど B2C シナリオではかなり有用な機能になるのではないかと思います。