简体   繁体   English

如何在MVC应用程序中使用JWT进行身份验证和授权?

[英]How to use JWT in MVC application for authentication and authorization?

I planned to use ASP.NET Identity 2.0 in an ASP.NET MVC application for authentication and authorization. 我计划在ASP.NET MVC应用程序中使用ASP.NET Identity 2.0进行身份验证和授权。

Referring the below link 参考以下链接

JSON Web Token in ASP.NET Web API 2 using Owin 使用Owin的ASP.NET Web API 2中的JSON Web令牌

I was able to create a access token(JWT) for the valid user ie, When user Logs in to the application I will validate the user with name and password then I will issue a JSON web token for that valid user. 我能够为有效用户创建访问令牌(JWT),即,当用户登录到应用程序时,我将使用名称和密码验证用户,然后为该有效用户颁发JSON Web令牌。

Now, I read in some articles that we need to pass the bearer token in headers for every request to validate the user for authentication. 现在,我读了一些文章,我们需要在每个请求的标头中传递承载令牌,以验证用户的身份验证。 In MVC we will provide Authorize attribute for the methods that needs to be protected as shown below… 在MVC中,我们将为需要保护的方法提供Authorize属性,如下所示……

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

How to tell my MVC application to use JWT for validating the user? 如何告诉我的MVC应用程序使用JWT验证用户?

I want to make my MVC application validate the user using JWT whenever the user tries to access the method with authorize attribute. 每当用户尝试访问带有authorize属性的方法时,我都希望我的MVC应用程序使用JWT验证用户。 Since I will use AJAX calls in many pages to access method present in MVC controller, I don't think it's good to pass a token on every AJAX request. 由于我将在许多页面中使用AJAX调用来访问MVC控制器中存在的方法,因此我认为在每个AJAX请求上传递令牌并不好。 I need help to accomplish authentication and authorization in an efficient way using ASP.NET Identity in an MVC applicaton. 我需要帮助,以在MVC应用程序中使用ASP.NET Identity高效地完成身份验证和授权。

Currently, I don't know how to use this JWT token for authentication and authorization in an MVC application. 目前,我不知道如何在MVC应用程序中使用此JWT令牌进行身份验证和授权。

In order for MVC to understand anything about your JWT you basically have to tell it :-) . 为了使MVC了解有关JWT的任何信息,您基本上必须告诉它:-)。 First, install the Jwt package from nuget: 首先,从nuget安装Jwt软件包:

Install-Package Microsoft.Owin.Security.Jwt

Then open up your Startup.cs file and add a new funtion that will tell MVC how to consume JWT. 然后打开您的Startup.cs文件并添加一个新功能,该功能将告诉MVC如何使用JWT。 At basics your Startup will look something like: 从根本上说,您的启动看起来像这样:

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) 
                }
            });
        }
    }
}

You will notice that I am placing the issuer, audienceId and audienceSecret in my Web.config file. 您会注意到,我在我的Web.config文件中放置了发行者,AudienceId和AudienceSecret。 (Those values should match the ones on your Resource Server). (这些值应与资源服务器上的值匹配)。 Also, you might want to ensure you have an updated System.IdentityModel.Tokens.Jwt running: 另外,您可能要确保已运行更新的System.IdentityModel.Tokens.Jwt:

Update-package System.IdentityModel.Tokens.Jwt

With those set, you may decorate your controller Action with the [Authorize] attribute and play ball. 设置好这些设置后,您可以使用[Authorize]属性装饰控制器Action并打球。

Play ball of course meaning fire your request from your javascript to your protected controller action: 当然,打球意味着将您的请求从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 By The way, if you wish to add the values in your web.config file in order to retrieve them as I did above; UPDATE的方式,如果你想添加的值在你的web.config文件,以便取回他们为我做以上; simply add them under the AppSettings: 只需将它们添加到AppSettings下:

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

...of course, replacing the "values" with your own ...当然,用您自己的“值”代替

I don't know if you solved this, but I was having a similar issue and decided to store the token using FormsAuthentication which I was able to encrypt the token, and on each request the cookie was passed back and then I could decrypt it to get the JWT and then pull out the roles/claims from and then use those roles to create and Identity Principal that would allow me to decorate my controller methods with [Authorize(Role="blah,blah")]. 我不知道您是否解决了这个问题,但是我遇到了类似的问题,并决定使用FormsAuthentication来存储令牌,该令牌能够对令牌进行加密,并且在每次请求时都将cookie传递回去,然后可以将其解密获取JWT,然后从中提取角色/声明,然后使用这些角色来创建和Identity Principal,这将允许我使用[Authorize(Role =“ blah,blah”)]装饰控制器方法。

Here is some sample code below. 这是下面的一些示例代码。

Once you get the JSON web token back from the api after login, you can use something like: 登录后从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)

I have some of my own created classes and methods in there, but it will give you the general idea that you store the JWT access token as well as the expiration date in your FormsAuthentication cookie. 我在那里有一些自己创建的类和方法,但是它将给您一个大致的想法,即您将JWT访问令牌以及过期日期存储在FormsAuthentication cookie中。

Then the cookie is passed with each request and in your Global.asax file you can have a method to authenticate the request: 然后,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;
    }
}

So that method you would decrypt the cookie to get the JWT access token which you can then decode using the System.IdentityModel.Tokens.Jwt library from Microsoft and then take those roles and ID and generate the principal and identity for the user which creates your user with the roles. 因此,您可以使用该方法解密Cookie以获取JWT访问令牌,然后可以使用Microsoft的System.IdentityModel.Tokens.Jwt库对其进行解码,然后采用这些角色和ID并为创建您的用户的用户生成主体和身份角色的用户。

Then those roles can be validated against the [Authorize] attribute. 然后可以根据[Authorize]属性验证这些角色。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM