Token Based Authentication using Asp.net Core Web Api

Using  Token Based Authentication, clients are not dependent on a specific authentication mechanism. A token is generated by the server  if the user is authenticated and send it back to the user.

So to acces  a specific ressource, the client must include the generated token in the header of subsequent requests and the Web API Server have some APIs to understand, validate the token and perform the autorization

This approach provides Loose Coupling between client and the Web API.

In my previous tutorial   Angular JS Token-based Authentication using Asp.net Identity and Asp.net web API   I have build an  authentication server using an oAuth Bearer Token.

In this tutorial, I will use JSON Web Token (JWT) , for more information about JWT please take a look at  https://jwt.io/

JWT enable us to securely transfer data between server and client .

A JWT Token is composed of 3 parts base64 encoded separated by a dot(.) : a header, a payload and a signature :  header.payload.signature

  • Header : contains a Typ (should be JWT) and  a Hashing algorithm HS256, RS512, ES356, etc…

  • Payload  contains the information witch we need to transfer to client such as Claims  related to the token

  • Signature    A Hash of Header and Payload using a secret Key

TokenSignature

JWT therefore allows to exchange content for an authenticated user due to the secret key used in the signature. The signature also ensures the integrity of the content.

Even if every one can  holds the token, he cannot tempored the payload due to the signature with the Secret Key.

SSL helps prevent against to MitM  (man-in-the-middle) attacks.

Untitled2

Securing our web application consists of two scenarios  Authentication and Authorisation

  1. Authentication identifies the user. so the user must be registered before, using login and password or third party logins like Facebook, Twitter,
  2. Authorisation  talks about  Permission for authenticated users
    – what is the user (authenticated) allowed to do ?
    – What ressources can the user access ?

I’m going to  build a Token-based Authentication  Server using ASP.Net Core Identity , ASP.Net Core Web API and Entity Framework Core

So lets create a new ASP.NET Core Web Application Project

CreateProjet

CreateProjet2

Dependencies

install this packages

install-package Microsoft.AspNetCore.Identity

install-package Microsoft.AspNetCore.Identity.EntityFrameworkCore

install-package Microsoft.EntityFrameworkCore.SqlServer

install-package Microsoft.EntityFrameworkCore.Tools

Setup Indentity database

Create a User model that inherits from IdentityUser and extend it with additional properties such as JoinDate, JobTitle and Contract.

MyUser

Create a Role model that inherits from IdentityRole and extend it with additional properties such as Role Description

MyRole

Create an IndentityContext that inherits from IdentityDbContext<MyUser>

IdentityContext

Create an AppSettings.json file and add a ConnectionString:  SecurityConnection

appSettings_Constr

Open StartUp.cs class , locate  ConfigureServices method :  ConfigureServices(IServiceCollection services)  and add the following to configure our SecurityContext to point to SecurityConnection witch point to sql database configured in AppSettings.json file

Configure Asp.Net Core Indentity to use our custom user and role ( MyUser and MyRole)

Services

Locate Configure method and add  app.UseIdentity  in middleware

Configuration

Open Package Manager Console.

Initialise migration  :    add-migration init

Upadate or Create the Database  : update-database

The generated database looks like this

BaseStructure

Register User

RegisterUser

  Test Register user

I use a google extensions Postman to test api

RegisterUser-2

RegisterUser-1

RegisterUser-3

Get Ressources

Here , I log the user , if the user is authenticated with its credentials (email and password), I get the user claims , add additionnal claims related to JWT, Create Security Token and return it

GenerateToken1GenerateToken2

Locate Configure method and app.UseJwtBearerAuthentication  in middleware  to validate the token

ConfigToken

The protected ressource  look like this

GetRessources

Test API With Postman

get token   (localhost:58834/api/auth/token)

GetToken

Send Query to get ressource by including valid token in the header (localhost:58834/api/values)

passtokentoheader

Send Query to get ressource by including invalid token in the header (localhost:58834/api/values)

passInvalidtokentoheader

The entire scenario

Code source is available on my Github repository (https://github.com/logcorner/token-based-authentification-using-asp.net-web-api-core)

Best regards

Gora LEYE

I’m a .NET Architect and Technical Expert skills located in Paris (FRANCE). The purpose of this blog is mainly to post general .NET tips and tricks,

  • Pingback: Asp.Net Web Api Core Integration testing using InMemory EntityFrameworkCore Sqlite or LocalDB and XUnit2 | LogCorner.com()

  • Pingback: Angular2 Token Based Authentication using Asp.net Core Web API and JSON Web Token | LogCorner.com()

  • Carlos Andres Sanchez Garcia

    How can I create a role based on this code sample, since the entity MyRole is not included in the model for the context?

    • LogCorner

      Hi,
      you do this :
      var userClaims = await _userManager.GetClaimsAsync(user); returns the role if the user has a role stored on tables userclaims.

      you can also add it ilke :
      var claims = new[]
      {
      new Claim(ClaimTypes.Role, “admin”),
      new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
      new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
      new Claim(JwtRegisteredClaimNames.Email, user.Email)
      }.Union(userClaims);

      if you want to manage roles from roles tables you can use :
      var user = await _userManager.FindByNameAsync(model.Email);
      var roles = _userManager.GetRolesAsync(user);
      var isInRole = _userManager.IsInRoleAsync(user, “admin”);
      Regards

      • Carlos Andres Sanchez Garcia

        I found you must replace the following line in order to include the role in the context, please let me know if I’m wrong:

        public class SecurityContext : IdentityDbContext

        • Not mandatory
          in startup.cs file we found a line that include the role :
          services.AddIdentity(cfg =>
          {….}

          MyUser also inherits from IdentityUser witch inherits from IdentityUser<TKey, IdentityUserClaim, IdentityUserRole, IdentityUserLogin>

          so we can access role and claims from IdentityUser

          in AuthController, we have also a property :
          private readonly RoleManager _roleManager;
          so we can also manager role like this :
          var role = _roleManager.RoleExistsAsync(“admin”);
          regards

  • Mansur Haider

    Thanks Gora, for sharing excellent article.