AspNetCore.Security.Jwt - JWT Bearer Token Security Package

I have built a package which integrates JWT Bearer Token Security into an Asp Net Core 2.0+ application.

I have built a package which integrates JWT Bearer Token Security into an Asp Net Core 2.0+ application.

The package

  • Makes adding JWT Bearer Token Security to your ASP NET Core 2.0+ app a breeze!!
  • Gives you an out of the box TokenController to issue Jwt tokens.
  • Integrates the TokenContoller into your app automatically.
  • Also, Swagger UI integration!

To use the package,

You can download/clone the source code from my GitHub repository

Then add a Reference to the project (AspNetCore.Security.Jwt) in your application.
 

Use Default authentication (Id, Password) 

Then, you can do the below steps,

Implement IAuthentication interface in your app

Validate the Id and Password here.

See Appendix A for the IdType supported.

After this validation, the Jwt token is issued by the TokenController.

  1. using AspNetCore.Security.Jwt;  
  2. using System.Threading.Tasks;  

  3. namespace XXX.API {  

  4.     public class Authenticator: IAuthentication {  

  5.         public async Task<bool> IsValidUser(string id, string password) {  
  6.             //Put your id authenication here.  
  7.             return true;  
  8.         }  
  9.     }  
  10. }  
The Authenticator is automatically wired up for dependency injection (Scoped). 
 
In your Startup.cs

Add the package to your application with the below in your app’s Startup.cs.

  1. using AspNetCore.Security.Jwt;  
  2. using Swashbuckle.AspNetCore.Swagger;  

  3. public void ConfigureServices(IServiceCollection services) {
  4.     ...

  5.     services.AddSwaggerGen(c => {  
  6.         c.SwaggerDoc("v1"new Info {  
  7.             Title = "XXX API", Version = "v1"  
  8.         });  
  9.     });  
  10.     services.AddSecurity<Authenticator>(this.Configuration, true);  
  11.     services.AddMvc().AddSecurity();  
  12. }
  13.   
  14. public void Configure(IApplicationBuilder app, IHostingEnvironment env)   
  15. {
  16.    ...   
  17.    // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),   
  18.    // specifying the Swagger JSON endpoint.   
  19.    app.UseSwaggerUI(c =>   
  20.    {   
  21.        c.SwaggerEndpoint("/swagger/v1/swagger.json""XXX API V1");   
  22.    });   

  23.    app.UseSecurity(true); 
  24.    app.UseMvc();   
  25. }  

In your appsettings.json

Add the SecuritySettings to the appsettings.json. These settings control the JWT token creation.

  1. {  
  2.     "SecuritySettings": {  
  3.         "Secret""a secret that needs to be at least 16 characters long",  
  4.         "Issuer""your app",  
  5.         "Audience""the client of your app",  
  6.         "IdType""Name",  
  7.         "TokenExpiryInHours": 2  
  8.     },  
  9.     ...  
  10. }  

Use custom User model authentication

 
Create your User model
 
Your custom User model must inherit from IAuthenticationUser. 
  1. using AspNetCore.Security.Jwt;  
  2. using System;  
  3. .  
  4. .  
  5. public class UserModel : IAuthenticationUser  
  6. {  
  7.     public string Id { getset; }  
  8.   
  9.     public string Password { getset; }  
  10.   
  11.     public string Role { getset; }  
  12.   
  13.     public DateTime DOB { getset; }  
  14. }  

Implement IAuthentication<TUserModel> interface in your app 

Validate your User model here.

After this validation, the Jwt token is issued by the TokenController.

  1. using AspNetCore.Security.Jwt;  
  2. using System.Threading.Tasks;  
  3.   
  4. namespace XXX.API  
  5. {  
  6.     public class Authenticator : IAuthentication<UserModel>  
  7.     {          
  8.         public async Task<bool> IsValidUser(UserModel user)  
  9.         {  
  10.             //Put your User model authenication here.  
  11.             return true;  
  12.         }  
  13.     }  
  14. }  

In your Startup.cs

Specify your IdTypes (ClaimTypes) from your custom User model using AddClaim.

Basically, this uses Claim under the covers. So you can verify these Claims in your Controller's action just as usual. See Appendix B.

All these ClaimTypes will be used in the token generation.

You can specify multiple Claim Types.

  1. using AspNetCore.Security.Jwt;  
  2. using Swashbuckle.AspNetCore.Swagger;..  
  3. public void ConfigureServices(IServiceCollection services) {..  
  4.     services.AddSwaggerGen(c => {  
  5.         c.SwaggerDoc("v1"new Info {  
  6.             Title = "XXX API", Version = "v1"  
  7.         });  
  8.     });  
  9.     services.AddSecurity < Authenticator, UserModel > (this.Configuration, builder => builder.AddClaim(IdType.Name, userModel => userModel.Id).AddClaim(IdType.Role, userModel => userModel.Role).AddClaim("DOB", userModel => userModel.DOB.ToShortDateString()), true);  
  10.     services.AddMvc().AddSecurity < UserModel > ();  
  11. }  
  12. public void Configure(IApplicationBuilder app, IHostingEnvironment env) {...  
  13.     // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),     
  14.     // specifying the Swagger JSON endpoint.    
  15.     app.UseSwaggerUI(c => {  
  16.         c.SwaggerEndpoint("/swagger/v1/swagger.json""XXX API V1");  
  17.     });  
  18.     app.UseSecurity(true);  
  19.     app.UseMvc();  
  20. }  

In your appsettings.json

  1. {  
  2.   "SecuritySettings": {  
  3.     "Secret""a secret that needs to be at least 16 characters long",  
  4.     "Issuer""your app",  
  5.     "Audience""the client of your app",  
  6.     "TokenExpiryInHours" :  2  
  7.   },  
  8.   .  
  9.   .  
  10.   .  
  11. }  

In your Controller that you want to secure

You must mark the Controller or Action that you want to secure with Authorize attribute like,

  1. using Microsoft.AspNetCore.Mvc;
  2. ...

  3. namespace XXX.API.Controllers {  
  4.     using Microsoft.AspNetCore.Authorization;
  5.   
  6.     [Authorize]
  7.     [Route("api/[controller]")] 
  8.     public class XXXController: Controller {
  9.       ...  
  10.     }  
  11. }  

TokenController - Issues the Jwt token

The TokenContoller has a POST Method which you can call with a Id and Password.

The Id has to match the specified IdType.

The POST in Postman is like below,

 JWT Bearer Token Security Package

A Jwt Bearer token is then issued which must be sent in subsequent requests in the header.

Access your secure Controller or Action

You have to send the issued Jwt token in the header of the request as

Authorization: Bearer <token>

Eg.

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1
LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiU2hhbiIsImV4cCI6MTU0MjUxMTkzOSwibmJmIjoxNTQwMDkyNzM5LCJpc3MiOiJ5
b3VyIGFwcCIsImF1ZCI6InRoZSBjbGllbnQgb2YgeW91ciBhcHAifQ.VktS3XGD-Z3-wNuXl4IuLLJXe9OUNK5RZ8o-9eUUVuE

to access the Controller or Action.

This is like below in Postman,

JWT Bearer Token Security Package 

In the Angular 2+ app, you can do this using HttpInterceptors.

Swagger UI integration

When you start Swagger you will see a Token endpoint automatically.

Also, you will see an Authorize button.

JWT Bearer Token Security Package 

You obtain the Jwt token by entering your Id and Password on the Token Endpoint.

Then you enter the token into the Value field after clicking on the Authorize button as,

AspNetCore.Security.Jwt - JWT Bearer Token Security Package

Then, you can make calls to all secured endpoints (marked with Authorize attribute).

Appendix A

IdType is an enum.

All ClaimTypes are available via this enum.

The IdType your app will use is specified in the SecuritySettings of your appsettings.json.

That can be any one of the ones specified in the enum below,
  1. public enum IdType  
  2. {  
  3.     Actor,  
  4.     PostalCode,  
  5.     PrimaryGroupSid,  
  6.     PrimarySid,  
  7.     Role,  
  8.     Rsa,  
  9.     SerialNumber,  
  10.     Sid,  
  11.     Spn,  
  12.     StateOrProvince,  
  13.     StreetAddress,  
  14.     Surname,  
  15.     System,  
  16.     Thumbprint,  
  17.     Upn,  
  18.     Uri,  
  19.     UserData,  
  20.     Version,  
  21.     Webpage,  
  22.     WindowsAccountName,  
  23.     WindowsDeviceClaim,  
  24.     WindowsDeviceGroup,  
  25.     WindowsFqbnVersion,  
  26.     WindowsSubAuthority,  
  27.     OtherPhone,  
  28.     NameIdentifier,  
  29.     Name,  
  30.     MobilePhone,  
  31.     Anonymous,  
  32.     Authentication,  
  33.     AuthenticationInstant,  
  34.     AuthenticationMethod,  
  35.     AuthorizationDecision,  
  36.     CookiePath,  
  37.     Country,  
  38.     DateOfBirth,  
  39.     DenyOnlyPrimaryGroupSid,  
  40.     DenyOnlyPrimarySid,  
  41.     DenyOnlySid,  
  42.     WindowsUserClaim,  
  43.     DenyOnlyWindowsDeviceGroup,  
  44.     Dsa,  
  45.     Email,  
  46.     Expiration,  
  47.     Expired,  
  48.     Gender,  
  49.     GivenName,  
  50.     GroupSid,  
  51.     Hash,  
  52.     HomePhone,  
  53.     IsPersistent,  
  54.     Locality,  
  55.     Dns,  
  56.     X500DistinguishedName  
  57. }  

Appendix B

Verify Claims in your Controller action.

This is done as usual. To map between IdType to ClaimTypes use ToClaimTypes() extension.

  1. using AspNetCore.Security.Jwt;  
  2. using Microsoft.AspNetCore.Authorization;  
  3. using Microsoft.AspNetCore.Mvc;  
  4. .  
  5. .  
  6. [HttpGet("cheapest/{title}")]  
  7. public async Task<IEnumerable<ProviderMovie>> GetCheapestDeal(string title)  
  8. {  
  9.     var currentUser = HttpContext.User;  
  10.   
  11.     //Verify Claim  
  12.     if (currentUser.HasClaim(x => x.Type == "DOB") && currentUser.HasClaim(x => x.Type == IdType.Role.ToClaimTypes()))  
  13.     {  
  14.         //Do something here  
  15.     }  
  16.   
  17.     return await _moviesRepository.GetCheapestDeal(title);  
  18. }    

Notes

The Package integrates JWT bearer token security into your app quickly.

But, you can modify the source code to suit the kind of Token you want to generate.

You can do this in the GenerateToken method of the SecurityService (in the SecurityService.cs code file).