web-dev-qa-db-ja.com

認証と承認のためにMVCアプリケーションでJWTを使用する方法は?

認証と承認のためにASP.NET MVCアプリケーションでASP.NET Identity 2.0を使用する予定でした。

以下のリンクを参照

Owinを使用したASP.NET Web API 2のJSON Web Token

有効なユーザーのアクセストークン(JWT)を作成できました。つまり、ユーザーがアプリケーションにログインすると、ユーザーを名前とパスワードで検証し、その有効なユーザーのJSON Webトークンを発行します。

今、私はいくつかの記事を読んで、認証のためにユーザーを検証するために、すべての要求に対してヘッダーでベアラートークンを渡す必要があることを読みました。 MVCでは、以下に示すように保護する必要があるメソッドのAuthorize属性を提供します…

      public class UserController : BaseHRAppController
      {
            [Authorize]
            public ActionResult Index()
            {          
               return View();
            }
       }

ユーザーの検証にJWTを使用するようにMVCアプリケーションに指示するにはどうすればよいですか?

ユーザーがauthorize属性でメソッドにアクセスしようとするたびに、MVCアプリケーションでJWTを使用してユーザーを検証するようにします。多くのページでAJAX呼び出しを使用してMVCコントローラーに存在するメソッドにアクセスするため、すべてのAJAXリクエストでトークンを渡すのは良いことではないと思います。MVCアプリケーションでASP.NET Identityを使用して、効率的な方法で認証と承認を行うための支援が必要です。

現在、MVCアプリケーションでの認証と承認にこのJWTトークンを使用する方法がわかりません。

37
SDK

MVCがJWTについて何かを理解するためには、基本的にそれを伝える必要があります:-)。まず、nugetからJwtパッケージをインストールします。

Install-Package Microsoft.Owin.Security.Jwt

次に、Startup.csファイルを開き、MVCにJWTを使用する方法を伝える新しい機能を追加します。基本的に、スタートアップは次のようになります。

using System.Configuration;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using Microsoft.Owin.Security.Jwt;
using Owin;

[Assembly: OwinStartupAttribute(typeof(TOMS.Frontend.Startup))]
namespace TOMS.Frontend
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            ConfigureOAuthTokenConsumption(app);
        }

        private void ConfigureOAuthTokenConsumption(IAppBuilder app)
        {
            var issuer = ConfigurationManager.AppSettings["Issuer"];
            var audienceId = ConfigurationManager.AppSettings["AudienceId"];
            var audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]);

            // Api controllers with an [Authorize] attribute will be validated with JWT
            app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[] { audienceId },
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret) 
                }
            });
        }
    }
}

Web.configファイルにissuer、audienceId、audienceSecretを配置していることがわかります。 (これらの値は、リソースサーバー上の値と一致する必要があります)。また、更新されたSystem.IdentityModel.Tokens.Jwtが実行されていることを確認したい場合があります。

Update-package System.IdentityModel.Tokens.Jwt

これらのセットを使用して、コントローラーのアクションを[Authorize]属性で装飾し、ボールをプレイできます。

もちろん、ボールをプレイして、JavaScriptから保護されたコントローラーアクションにリクエストを送信します。

//assuming you placed the token in a sessionStorage variable called tokenKey when it came back from your Authorization Server
    var token = sessionStorage.getItem(tokenKey);
    var headers = {};
    if (token) {
        headers.Authorization = 'Bearer ' + token;
    }

    $.ajax({
        type: 'GET',
        url: 'CONTROLLER/ACTION',
        headers: headers
    }).done(function (data) {
        self.result(data);
    }).fail(showError);

[〜#〜] update [〜#〜]ところで、上記のようにweb.configファイルに値を追加して取得する場合は、 AppSettingsの下に追加するだけです。

<configuration>
 <appSettings>
    <add key="Issuer" value="YOUR_ISSUER" />
    <add key="AudienceId" value="YOUR_AUDIENCEID" />
    <add key="AudienceSecret" value="YOUR_AUDIENCESECRET" />
 </appSettings>
</configuration>

...もちろん、「値」を独自のものに置き換えます

43

これを解決したかどうかはわかりませんが、同様の問題が発生していたため、トークンを暗号化できるFormsAuthenticationを使用してトークンを保存することを決定し、リクエストごとにCookieが返され、復号化することができましたJWTを取得してからロール/クレームを引き出し、それらのロールを使用して、[Authorize(Role = "blah、blah")]でコントローラーメソッドを装飾できるようにするIDプリンシパルを作成します。

以下にサンプルコードを示します。

ログイン後にAPIからJSON Webトークンを取得したら、次のようなものを使用できます。

var returnedToken = (TokenResponse)result.ReturnedObject;
var ticket = new FormsAuthenticationTicket(1, model.Email, DateTime.Now, ConvertUnitToDateTime(returnedToken.expires_in), true, returnedToken.access_token);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie)

そこには自分で作成したクラスとメソッドがいくつかありますが、FormsAuthentication CookieにJWTアクセストークンと有効期限を保存するという一般的な考え方がわかります。

次に、Cookieが各リクエストとともに渡され、Global.asaxファイルにリクエストを認証するメソッドを含めることができます。

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        //Extract the forms authentication cookie
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JwtSecurityToken jwTok = TokenHelper.GetJWTokenFromCookie(authCookie); 

        // Create the IIdentity instance
        IIdentity id = new FormsIdentity(authTicket);

        // Create the IPrinciple instance
        IPrincipal principal = new GenericPrincipal(id, TokenHelper.GetRolesFromToken(jwTok).ToArray());

        // Set the context user
        Context.User = principal;
    }
}

そのため、Cookieを復号化してJWTアクセストークンを取得し、MicrosoftのSystem.IdentityModel.Tokens.Jwtライブラリを使用してデコードし、それらのロールとIDを取得して、ユーザーを作成するユーザーのプリンシパルとIDを生成します。役割を持つユーザー。

次に、これらのロールを[Authorize]属性に対して検証できます。

11
reverence12389