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

SDK picture SDK · Apr 22, 2015 · Viewed 64.4k times · Source

I planned to use ASP.NET Identity 2.0 in an ASP.NET MVC application for authentication and authorization.

Referring the below link

JSON Web Token in ASP.NET Web API 2 using Owin

I was able to create a access token(JWT) for the valid user i.e., 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.

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…

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

How to tell my MVC application to use JWT for validating the user?

I want to make my MVC application validate the user using JWT whenever the user tries to access the method with authorize attribute. 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. I need help to accomplish authentication and authorization in an efficient way using ASP.NET Identity in an MVC applicaton.

Currently, I don't know how to use this JWT token for authentication and authorization in an MVC application.

Answer

Houdini Sutherland picture Houdini Sutherland · Sep 30, 2015

In order for MVC to understand anything about your JWT you basically have to tell it :-) . First, install the Jwt package from nuget:

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. 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. (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:

Update-package System.IdentityModel.Tokens.Jwt

With those set, you may decorate your controller Action with the [Authorize] attribute and play ball.

Play ball of course meaning fire your request from your javascript to your protected controller action:

//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; simply add them under the 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