[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]

-[[戻る>ASP.NET Identity]]

* 目次 [#y767ea78]
#contents

*概要 [#x51e7243]
[[ASP.NET Identity]]は、~
[[OAuth]]の[[クレームベース認証]]のEndpoint追加をサポートしており、~
これにより、JavaScript などの「非 .NET 環境」と連携させることもできる。

この処理は、SPAテンプレートの以下のエンドポイントに実装されている。
 
-ASP.NET SPA (JavaScript) の Web API 認証 (ASP.NET Identity) ? Tsmatz~
https://blogs.msdn.microsoft.com/tsmatsuz/2014/05/20/asp-net-spa-javascript-web-api-asp-net-identity-html5biz/
--http://localhost:XXXX/Token
--http://localhost:XXXX/Account/Authorize

ここでは、
+SPAテンプレートの動作確認を行い、
+MVCテンプレートの差分を確認した上で、
+[[OAuth]]のEndpoint追加に必要な実装を抽出し、
+MVCテンプレートに[[OAuth]]のEndpointを追加する手順を書き出し、
+その手順の妥当性を以下の検証手順によって検証した。

*検証手順 [#p5f5a8e3]
**前提 [#cac6a33f]
ここでは、以下のような前提のアプリケーションを構築するサンプルを示す。

#ref(goal.png,left,nowrap,50%,アプリケーション構成)

***認証サイト [#l4133d0e]
-ASP.NET MVC アプリケーションとして作成する。
-ASP.NET Identity を用いて、各 Web アプリのアカウント管理を行う。
-ユーザー情報へのアクセスには、既定の Entity Framework を使用する。
-ユーザー情報は、既定の LocalDb に格納する。

***Web アプリ [#o744ec42]
-個々の Web アプリではアカウント管理は行わず、~
アカウント管理が必要な場合は認証サイトにリクエストする。
-Java Web アプリケーションとして作成する。

***開発環境 [#heed732c]
-認証サイト側
--Visual Studio 2015
--プログラム言語は C#

-Web アプリ側
--Eclipse 4.6 Neon
--プログラム言語は Java

**認証サイト開発 [#k9408908]
***プロジェクトの準備 [#jcb91f7a]
+Visual Studio 2015 で、新規 ASP.NET Web アプリケーションを作成する。
+「新しい ASP.NET プロジェクト」ダイアログで、以下を選択する。
--テンプレート: MVC
--認証の変更: 個別のユーザー アカウント
+Visual Studio の「パッケージ マネージャー コンソール」で、以下のコマンドを実行する。
 Install-Package Microsoft.AspNet.WebApi
 Install-Package Microsoft.AspNet.WebApi.Owin
 Install-Package Microsoft.AspNet.WebApi.Cors

***ApplicationOAuthProviderの追加 [#z15e0624]
Providers フォルダを作成し、以下の ApplicationOAuthProvider.cs を作成する。

 namespace [名前空間名].Providers
 {
     public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
     {
         private readonly string _publicClientId;
 
         public ApplicationOAuthProvider(string publicClientId)
         {
             if (publicClientId == null)
             {
                 throw new ArgumentNullException("publicClientId");
             }
 
             _publicClientId = publicClientId;
         }
 
         public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
         {
             if (context.ClientId == _publicClientId)
             {
                 Uri expectedRootUri = new Uri(context.Request.Uri, "/");
 
                 if (expectedRootUri.AbsoluteUri == context.RedirectUri)
                 {
                     context.Validated();
                 }
                 else if (context.ClientId == "web")
                 {
                     var expectedUri = new Uri(context.Request.Uri, "/");
                     context.Validated(expectedUri.AbsoluteUri);
                 }
             }
 
             return Task.FromResult<object>(null);
         }
     }
 }

***Startup.Auth.csに追加実装 [#n71f912c]
「// 以下、追加部分」~「// ここまで」の範囲。

 public partial class Startup
 {
     // 以下、追加部分
     // アプリケーションによる OAuthAuthorization の使用を有効にします。その後に Web API を保護できます
     static Startup()
     {
         PublicClientId = "web";
 
         OAuthOptions = new OAuthAuthorizationServerOptions
         {
             TokenEndpointPath = new PathString("/Token"),
             AuthorizeEndpointPath = new PathString("/Account/Authorize"),
             Provider = new ApplicationOAuthProvider(PublicClientId),
             AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
             AllowInsecureHttp = true
         };
     }
 
     public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
 
     public static string PublicClientId { get; private set; }
     // ここまで
 
     // 認証設定の詳細については、http://go.microsoft.com/fwlink/?LinkId=301864 を参照してください
     public void ConfigureAuth(IAppBuilder app)
     {
         // 1 要求につき 1 インスタンスのみを使用するように DB コンテキスト、ユーザー マネージャー、サインイン マネージャーを構成します。
         app.CreatePerOwinContext(ApplicationDbContext.Create);
         app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
         app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
 
         // アプリケーションが Cookie を使用して、サインインしたユーザーの情報を格納できるようにします
         // また、サードパーティのログイン プロバイダーを使用してログインするユーザーに関する情報を、Cookie を使用して一時的に保存できるようにします
         // サインイン Cookie の設定
         app.UseCookieAuthentication(new CookieAuthenticationOptions
         {
             AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
             LoginPath = new PathString("/Account/Login"),
             Provider = new CookieAuthenticationProvider
             {
                 // ユーザーがログインするときにセキュリティ スタンプを検証するように設定します。
                 // これはセキュリティ機能の 1 つであり、パスワードを変更するときやアカウントに外部ログインを追加するときに使用されます。
                 OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                     validateInterval: TimeSpan.FromMinutes(30),
                     regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
             }
         });            
         app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
 
         // 2 要素認証プロセスの中で 2 つ目の要素を確認するときにユーザー情報を一時的に保存するように設定します。
         app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
 
         // 2 つ目のログイン確認要素 (電話や電子メールなど) を記憶するように設定します。
         // このオプションをオンにすると、ログイン プロセスの中の確認の第 2 ステップは、ログインに使用されたデバイスに保存されます。
         // これは、ログイン時の「このアカウントを記憶する」オプションに似ています。
         app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
 
         // 以下、追加部分
         // アプリケーションがベアラ トークンを使用してユーザーを認証できるようにします
         app.UseOAuthBearerTokens(OAuthOptions);
         // ここまで
 
         // 次の行のコメントを解除して、サード パーティのログイン プロバイダーを使用したログインを有効にします
         //app.UseMicrosoftAccountAuthentication(
         //    clientId: "",
         //    clientSecret: "");
 
         //app.UseTwitterAuthentication(
         //   consumerKey: "",
         //   consumerSecret: "");
 
         //app.UseFacebookAuthentication(
         //   appId: "",
         //   appSecret: "");
 
         //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
         //{
         //    ClientId = "",
         //    ClientSecret = ""
         //});
     }
 }

***OAuthClaimViewModelの追加 [#me6fe947]
Models フォルダに、クレームを返すための OAuthClaimViewModel.cs を追加する。

 namespace [名前空間名].Models
 {
     // MeController アクションによって返されるモデル。
     public class OAuthClaimViewModel
     {
         public string Hometown { get; set; }
     }
 }

**Web アプリ開発 [#zda88633]

*参考 [#f733c473]
-ASP.NET SPA (JavaScript) の Web API 認証 (ASP.NET Identity) – Tsmatz~
https://blogs.msdn.microsoft.com/tsmatsuz/2014/05/20/asp-net-spa-javascript-web-api-asp-net-identity-html5biz/

-ASP.NET WebAPI2でAjaxでOAuth認証するよ(ついでにTypeScriptとReact) - かずきのBlog@hatena~
http://blog.okazuki.jp/entry/2016/01/15/215901


----
Tags: [[:ASP.NET]], [[:ASP.NET Identity]]

Special thanks go to maegawa-san for his support.

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS