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

C#asp.net Mvc-4AuthenticationAuthorizationasp.net Identity

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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")].

Here is some sample code below.

Once you get the JSON web token back from the api after login, you can use something like:

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.

Then the cookie is passed with each request and in your Global.asax file you can have a method to authenticate the request:

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.

Then those roles can be validated against the [Authorize] attribute.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSDKView Question on Stackoverflow
Solution 1 - C#Houdini SutherlandView Answer on Stackoverflow
Solution 2 - C#reverence12389View Answer on Stackoverflow