0% found this document useful (0 votes)
21 views48 pages

JWT Authentication English STEP by STEP

.Net 8 JSON Web Authentication (JWT) provides a comprehensive guide for implementing JWT authentication in .Net applications. The document outlines steps including updating the database context, adding necessary NuGet packages, creating authentication methods, and configuring controllers for user registration and login. It also includes instructions for setting up JWT token generation and validation, as well as testing authentication using Swagger.

Uploaded by

manish.aka.mani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views48 pages

JWT Authentication English STEP by STEP

.Net 8 JSON Web Authentication (JWT) provides a comprehensive guide for implementing JWT authentication in .Net applications. The document outlines steps including updating the database context, adding necessary NuGet packages, creating authentication methods, and configuring controllers for user registration and login. It also includes instructions for setting up JWT token generation and validation, as well as testing authentication using Swagger.

Uploaded by

manish.aka.mani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

.

Net TIPS JSON Web Authentication (JWT)

.Net 8 JSON Web Authentication


Step by step

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

Summary
I – Introduction ................................................................................................................................................................................. 4

II – Update the Context: replace “DbContext” with “IdentityDbContext” ................................................................................. 5


II-A Installing the NuGet “Microsoft.AspNetCore.Identity.EntityFrameworkCore” .................................................................... 5
II-A-1 Added “using Microsoft.AspNetCore.Identity.EntityFrameworkCore” ........................................................................ 6
II-B Reminder: How to find out the .Net version of the solution .................................................................................................... 7

III Start creating the database ......................................................................................................................................................... 8


III – A SQL Server - Retrieve connection information (connection string) .................................................................................... 8
III – B SQL SERVER - Program.cs ➔ Start database creation.................................................................................................... 9

IV Adding JWT rules ..................................................................................................................................................................... 10


IV-A "appsettings.json" - Added key for Token calculation ......................................................................................................... 10
IV-B Create a “SecurityMethods” folder ..................................................................................................................................... 11
IV-C Install the “System.IdentityModel.Token.JWT” package .................................................................................................... 12
IV-D Install the “Microsoft.AspNetCore.Authentication.JwtBearer” package ........................................................................... 16
IV-E Creation of the “SecurityMethods” class ............................................................................................................................ 17
IV-E-1 Location of the "SecurityMethods" class .................................................................................................................... 17
IV-E-2 Code of the “AddCustomAuthentication” method: This is where the key is used to calculate the Token ................. 18
IV-F Calling the “AddCustomAuthentication()” method in the “Program.cs” class .................................................................. 20
IV-F-1 The “Program.cs” class ............................................................................................................................................... 20
IV-F-2 Line of code ................................................................................................................................................................. 20

V Configuring the “Context Identity”........................................................................................................................................... 21


V-A Installing the NuGet “Microsoft.AspNetCore.Identity.UI” .................................................................................................. 21
V- B - (.Net 8) Implementation in the “Program.cs” class .......................................................................................................... 23
V-B-1 Code to insert into the “Program.cs” class ....................................................................................................................... 23
V-B-2 Presentation of the class “Program.cs” with the code inserted ..................................................................................... 23

VI Added the “AuthenticateController” controller ..................................................................................................................... 24


VI-A Procedure for adding the controller .................................................................................................................................... 24
VI-B Declaring variables in the “AuthenticateController” controller (with versioning syntax) ................................................. 27
VI-C Declaring variables in the “AuthenticateController” controller (without versioning syntax)............................................ 28
VI-D “AuthenticateController” constructor code........................................................................................................................ 28
VI-E The constructor’s code as it should appear ......................................................................................................................... 29

VII Added the Dto (Data Transfer Object) “AuthenticateUserDto ........................................................................................... 30


VII-A Creating an “Applications” folder ..................................................................................................................................... 30
VII-B Creating a “DTOs” folder ................................................................................................................................................. 31
VII-C Added the “AuthenticateUserDto” DTO ........................................................................................................................... 32

VIII Added the “Register” method in the “AuthenticateController” controller ...................................................................... 34


VIII-A The Code of the “Register” Method ................................................................................................................................. 34
VIII-B The "[DBO]AspNetUsers" table contains registration information. ................................................................................ 35
VIII-C The code of the private method "GenerateJwtToken"....................................................................................................... 362

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)
IX Added the “Login” method in the “AuthenticateController” controller .............................................................................. 37
IX-A The code for the public method "Login" .............................................................................................................................. 37

X The “DynamicResponseController” controller ........................................................................................................................ 39


X-A Added the “[Authorize]” attribute ........................................................................................................................................ 39

XI Improve the configuration…. ................................................................................................................................................... 40


XI-A Create a “SecurityOptions” class to store the Token calculation key ................................................................................. 40
XI-B Modify the "AddCustomAuthentication" method of the "SecurityMethods" class ............................................................... 43

XII Test authentication with swagger ........................................................................................................................................... 44


XII-A Configure Swagger in the “Program.cs” class for Token input ........................................................................................ 44
XII-A-1 What we want to achieve........................................................................................................................................... 44
XII-A-2 The code to insert into the “Program.cs” class .......................................................................................................... 48

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

I – Introduction

• Summary of JWT Authentication implementation

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

II – Update the Context: replace “DbContext” with “IdentityDbContext”


II-A Installing the NuGet
“Microsoft.AspNetCore.Identity.EntityFrameworkCore”

You need to replace


"DbContext" with
"IdentityDbContext"

Install this package

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

In the NuGet package manager, choose


“Microsoft.AspNetCore.Identity.EntityFrameworkCore”

My .Net version is 8.0.3: you need to choose the correct NuGet version from the list.

II-A-1 Added “using Microsoft.AspNetCore.Identity.EntityFrameworkCore”

In the “DataContext ” class, add the missing “using ”.

Don't forget to add the missing using


for using "IdentityDbContext"

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

II-B Reminder: How to find out the .Net version of the solution

Double-click on the
“API.Response.Dynamic.Model.Infrastructures” project: you
will see the current version of .Net used by the project.

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

III Start creating the database

III – A SQL Server - Retrieve connection information (connection string)

Right mouse button and


choose "Properties".

Chain to copy

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

III – B SQL SERVER - Program.cs ➔ Start database creation

In the "Program.cs" class, the code below will initiate database creation.

Note: The database will only be created if it does NOT already exist.

// - - - - - - - - - - - - - - -
// > Automatic database creation <
// - - - - - - - - - - - - - - -
using (var scope = app.Services.CreateScope())
{
// -- Loading tables defined in the context-
var dbContext = scope.ServiceProvider.GetService<DataContext>();

// -- Creating tables--
dbContext.Database.EnsureCreated();
}

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

IV Adding JWT rules


IV-A "appsettings.json" - Added key for Token calculation

You must declare the key that will be used for the token calculation algorithm in the
appsettings.json file.

Below is an example of a key:

"Jwt": {
"key": "A4e78145A369874AAjrt@128545!p@AyQ"
},

10

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

IV-B Create a “SecurityMethods” folder

11

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

IV-C Install the “System.IdentityModel.Token.JWT” package

12

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)
When you click on “Install-Package System.IdentityModel.Tokens.Jwt”, you arrive on the page
below:

Link : https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/

• The above page is shown for


informational purposes.

• We will not use this method to install


our package.

13

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

Right-click on the
“API.Response.Dynamic.Model” project

Then choose “Manage NuGet packages…”

14

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

The package "System.IdentityModel.Token.Jwt"


has been successfully added to the project
"API.Response.Dynamic.Model"
15

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

IV-D Install the “Microsoft.AspNetCore.Authentication.JwtBearer” package

Caution: You must select the


correct target .Net version.

The NuGet
"Microsoft.AspNetCore.Authentication.JwtBearer"
is successfully added to the
"API.Response.Dynamic.Model" project
16

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

IV-E Creation of the “SecurityMethods” class


IV-E-1 Location of the "SecurityMethods" class

The static class "SecurityMethods"


is in the "SecurityMethods" folder
of the
"API.Response.Dynamic.Model"
project

17

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)
IV-E-2 Code of the “AddCustomAuthentication” method: This is where the key is
used to calculate the Token

// > JWT Authentication <


using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

namespace API.Response.Dynamic.Model.SecurityMethods
{
public static class SecurityMethods
{
#region properties
// > Key statement for the construction of the Token <
private static string MyKeyJwt { get; set; }

private static string[]? args { get; set; }

#endregion
/// <summary>
/// Building the JWT Authentication Process
/// </summary>
/// <param name="_builder"></param>
/// <returns></returns>
public static object AddCustomAuthentication( object _builder)
{
// > 1/ Creating a "configurationBuilder" <
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

// > 2/ Creating a "Configuration" object from the...


// ..."configurationBuilder" <
IConfiguration configuration = configurationBuilder.Build();

// > 3/ We declare a "builder" variable of type...


// ... "WebAplicationBuilder" <
var builder = WebApplication.CreateBuilder(args);

// > 4 If the parameter passed is not null, then we retrieve its contents <
if ( _builder is not null)
{
// > We parse "_builder" with the "WebApplicationBuilder" class <
builder = (WebApplicationBuilder) _builder; ;
}

// > 5/ Retrieving the authentication key <


// ( We retrieve the key from "appsettings.json" )
MyKeyJwt = string.Empty;
MyKeyJwt = builder.Configuration.GetSection("Jwt")["key"];

18

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)
// =-=-=-=-=-=-=-=-=-=-
// = = = = START Phase Validation of the <Json Web Token> =-=-=-=
// =-=-=-=-=-=-=-=-=-=-
// > On détermine ici quelle est la façon de communiquer des Headers...
// ...dans la partie authentification.

builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

}).AddJwtBearer(options =>
{
// > This is where you configure jwt with all the parameters.<
{
// > We save the Token so we can use it later <
options.SaveToken = true;

// > Token Validation Parameters <


options.TokenValidationParameters = new TokenValidationParameters()
{
// > On va paramétrer notre Token avec la clé.
// > Celle ci est encodée (=>"SymmetricSecurityKey") <
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(MyKeyJwt)),

ValidateAudience = false,

ValidateIssuer = false,

ValidateActor = false,

// > The Token is said to have a limited lifespan.<


ValidateLifetime = true

};

}
});

// =-=-=-=-=-=-=-=-=-=-
// =-=-=- END Phase Validation of the <Json Web Token> =-=-=-=
// =-=-=-=-=-=-=-=-=-=-

return builder;

}
}
}

19

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

IV-F Calling the “AddCustomAuthentication()” method in the “Program.cs”


class
IV-F-1 The “Program.cs” class

The "Program.cs" class belongs to the "API.Response.Dynamic.Model" project.

This is why it is possible to directly call the “AddCustomAuthentication” method of


the static “SecuriryMethods” class.

IV-F-2 Line of code

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// ### *** JWT .Net 8 *** ####
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SecurityMethods.AddCustomAuthentication(builder);

20

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

V Configuring the “Context Identity”

V-A Installing the NuGet “Microsoft.AspNetCore.Identity.UI”

In the “API.Response.Dynamic.Model” project:

(1) – Right click on “Dependencies”


(2) – Select “Manage NuGet Packages”
(3)

21

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

Step 3 ➔Don’t forget to choose the correct target version of .Net (the solution is in .Net 8.2)

The Nuget “Microsoft.AspNetCore.Identity.UI” is installed in the


project “API.Response.Dynamic.Model”

22

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

V- B - (.Net 8) Implementation in the “Program.cs” class

V-B-1 Code to insert into the “Program.cs” class


// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// ### *** JWT .Net 8 *** ###
// ### > Password options settings ###
// ### > Context association ###
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
// > We ask what the password is...
// ...contains numbers <
options.Password.RequireDigit = true;

// > We ask what the password is...


// ...contains capital letters <
options.Password.RequireUppercase = true;

// > We ask what the password is...


// ..contains at least 12 characters <
options.Password.RequiredLength = 12;

// Association with our Context to perform authentication


}).AddEntityFrameworkStores<DataContext>();

V-B-2 Presentation of the class “Program.cs” with the code inserted

The “Program.cs” class with


the inserted code.

23

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VI Added the “AuthenticateController” controller


VI-A Procedure for adding the controller

Add a controller

- Right-click on the "V1_DB2400" folder (1),


- Select "Add" (2),
- Select "Controller" (3).

24

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

Add a controller

- Select "API" (1),


- Select "API Controller - Empty" (2),
- Confirm with "Add" (3)

25

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

C
Add a controller

- Select "API Controller" - empty (1),


- Name the controller "AuthenticateController" (2)
- Validate (3).

26

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VI-B Declaring variables in the “AuthenticateController” controller (with


versioning syntax)

In this version of the code, I use versioning (”using Asp.Versioning”).


See below for the version without versioning

using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace API.Response.Dynamic.Model.Controllers.V1_DB2400
{
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class AuthenticateController : ControllerBase
{
#region fields
// - - - - - - - - - - - -
// ### Authentication Start ###
// - - - - - - - - - - - -
// > Declares a "UserManager" <
private UserManager<IdentityUser> _userManager = null;

// > Declare valid to extract the key from "Jwt:Key" <


private string ElemKey;

// > Array of strings used to construct...


// ...the "host" object <
private string[] Elems = null;
// - - - - - - - - - - - -
// ### Authentication End ###
// - - - - - - - - - - - -
#endregion

27

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VI-C Declaring variables in the “AuthenticateController” controller (without


versioning syntax)

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace API.Response.Dynamic.Model.Controllers.V1_DB2400
{
[Route("api/[controller]")]
[ApiController]
public class AuthenticateController : ControllerBase
{
#region fields
// - - - - - - - - - - - -
// ### Authentication Start ###
// - - - - - - - - - - - -
// > Declares a "UserManager" <
private UserManager<IdentityUser> _userManager = null;

// > Declare valid to extract the key from "Jwt:Key" <


private string ElemKey;

// > Array of strings used to construct...


// ...the "host" object <
private string[] Elems = null;
// - - - - - - - - - - - -
// ### Authentication Fin ###
// - - - - - - - - - - - -
#endregion

VI-D “AuthenticateController” constructor code


#region Constructor
// > Constructor <
// Note: We retrieve "userManager" by dependency injection <

public AuthenticateController(UserManager<IdentityUser> userManager)


{
// > Loading the Parameter<
this._userManager = userManager;

// > We construct a "Host" object to be able to...


// ...manipulate an "appsettings.json" <
using IHost host = Host.CreateDefaultBuilder(Elems).Build();
IConfiguration config = host.Services.GetService<IConfiguration>();

// > We extract the value of the key "JWT:Key" from the "AppSettings"<
ElemKey = config.GetValue<string>("Jwt:Key");

}
#endregion
}
}

28

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VI-E The constructor’s code as it should appear

The "AuthenticateController" controller


code (versioning mode)

29

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VII Added the Dto (Data Transfer Object) “AuthenticateUserDto


Note: The "AuthenticateUserDto" class contains all the login information.

If the login is successful (see the "Login" method of the "AuthenticateController" controller), the calculated Token is
returned (via the "Token" property).

VII-A Creating an “Applications” folder

Create the “Applications” folder in the


“API.Response.Dynamic.Model” project

30

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VII-B Creating a “DTOs” folder

Create the “DTOs” subfolder in the “Applications” folder, still


in the “API.Response.Dynamic.Model” project.

31

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VII-C Added the “AuthenticateUserDto” DTO

Right-click on the “DTOs” folder,


and choose “Add New Item”.
- Select "Class" (1),
- Give the class a name ("AuthenticateUserDto") (2),
- Validate (3).

32

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

namespace API.Response.Dynamic.Model.Applications.DTOs
{
public class AuthenticateUserDto
{
#region properties

// > The Login will contain the email<


public string Login { get; set; }

public string Password { get; set; }

public string Name { get; set; }

// > Token calculated and returned <


public string Token { get; set; }

// > Contains possible error message <


public string ErrorMsge { get; set; }

#endregion
}
}

33

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VIII Added the “Register” method in the “AuthenticateController”


controller
The “Register” method will allow the caller to register (email address + password) in the authentication system.

VIII-A The Code of the “Register” Method

#region methods

[Route("Register")]
[HttpPost]
public async Task<IActionResult> Register([FromBody] AuthenticateUserDto userDto)
{
// > By default, pessimistic<
IActionResult result = this.BadRequest();

// ---------------------------
// ## START - Constructs the "user" object ##
// ---------------------------
var user = new IdentityUser(userDto.Login);
user.Email = userDto.Login;
user.UserName = userDto.Name;
// ---------------------------
// ## END - Constructs the "user" object ##
// ---------------------------

// > Attempting to write to the new User Base <


var success = await this._userManager.CreateAsync(user, userDto.Password);

if (success.Succeeded)
{
try
{
// > We retrieve the Token calculated by the "GenerateJwtToken" method <
userDto.Token = this.GenerateJwtToken(user);

// > We return the Dto with the calculated Token <


result = this.Ok(userDto);
}

// > Anomaly detected during token generation ? <


catch (Exception ex)
{
StringBuilder sb = new StringBuilder();

// > Identification of the message code <


sb.Append("JWT_ERR_REGISTER_A1 - ");

// > Retrieving the error message <


sb.Append(ex.Message);
userDto.ErrorMsge = sb.ToString();

// > We return the Dto with the error message <


result = this.BadRequest(userDto);
}

finally
{}
}

34

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)
// > Something went wrong <
// - Incorrect password: does NOT comply with the predefined rules,
// or
// - A user with this login already exists...
else
{
StringBuilder sb = new StringBuilder();

// > Identification of the message code <


sb.Append("JWT_ERR_REGISTER_A2 - ");

foreach ( char item in success.Errors.ToString())


{
sb.Append(item);
}

userDto.ErrorMsge = sb.ToString();
result = this.BadRequest(userDto);
}

return result;
}

VIII-B The "[DBO]AspNetUsers" table contains registration information.


.

The password is encrypted by the Framework.

35

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

VIII-C The code of the private method "GenerateJwtToken"


The “GenerateJwtToken” method can be placed in the “AuthenticateController” controller (this is the controller that contains the
“Register” method and the “Login” method).

This method “GenerateJwtToken” is responsible for calculating the Token: it is returned in the DTO “AuthenticateUserDto”.

Here is the code for “GenerateJwtToken” which is called by the “Login” method (see below), and therefore also the “Register” method.

Below is the code for the “GenerateJwtToken” method:

private string GenerateJwtToken( IdentityUser user)


{
// We define the Jwt token which will be responsible...
// ...of the creation of our Token <
var jwtTokenHandler = new JwtSecurityTokenHandler();

// > We retrieve our secret code from "app.settings" <


// ( Caution: Work with "UTF8" here because in the method...
// ..."AddCustomAuthentication" of the "SecurityMethods" class...
// ..in which the TOKEN is described, "UTF8" is declared. )

// (It is important to keep the same parameters, otherwise the...


// ...Framework will NOT be able to compare).
var key = Encoding.UTF8.GetBytes(ElemKey);

// -----------------------------
// --- Token Description ----
// -----------------------------
// > We need to use "claims"...
// ...which are properties in our token that provide...
// ...information about the token belonging to the user...
// ...and so we have information such as the user's ID,...
// ...the user's name, their email address...
// ...The good thing is that this information is generated by...
// ...our server and our identity framework, which are valid and reliable.

var tokenDescriptor = new SecurityTokenDescriptor


{
Subject = new System.Security.Claims.ClaimsIdentity(new[]
{
new Claim("Id",user.Id),
new Claim(JwtRegisteredClaimNames.Sub,user.Email) ,
new Claim(JwtRegisteredClaimNames.Email,user.Email),
// > The JTI is used for our Token <
new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())
}),

// > The Token will have a duration of three minutes <


Expires = DateTime.UtcNow.AddMinutes(3),

// > Here we add information about the encryption algorithm...


// ...which will be used to decrypt our token <
SigningCredentials = new SigningCredentials(

// > Caution: Working with "SymmetricSecurityKey" here because...


// ...in the "addCustomAuthentication" method of the class...
// ..."SecurityMethods" in which we describe the "TOKEN", ...
// ...we declare the "SymmetricSecurityKey". <
// > It is important to keep the same parameters, otherwise...
// ...the FrameWork will NOT be able to compare <
new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};

var token = jwtTokenHandler.CreateToken(tokenDescriptor);


var JwtToken = jwtTokenHandler.WriteToken(token);
return JwtToken;
}

36

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

IX Added the “Login” method in the “AuthenticateController” controller


The “Login” method will allow the caller to identify themselves (email address + password)

Note: The "Login" method of the "AuthenticateController" controller performs a login test with the password contained in the
"AuthenticateUserDto" DTO which will be in the "body" ("[FromBody ]") of the http request.

IX-A The code for the public method "Login"

Note: Remember to add the using " using API.Response.Dynamic.Model.Applications.DTOs; ;" in the
"AuthenticateController" controller.

[Route("Login")]
[HttpPost]
public async Task<IActionResult> Login([FromBody] AuthenticateUserDto DtoUser)
{
// > By default, pessimistic <
IActionResult result = this.BadRequest();

// > We'll verify the profile using the email address and password <
// > The idea is to be able to authenticate with the login that...
// ...IS the email address. <
// > Since we're searching using the email address (contained in...
// ...the login, we use the "FindByEmailAsync" method <

// > Reminder: when our "Login" method is "async",...


// ...we must do an "await" <
var user = await this._userManager.FindByEmailAsync(DtoUser.Login);

if (user != null)
{
// > We will check the password <
var verif = await this._userManager.CheckPasswordAsync(user, DtoUser.Password);
if (verif)
{
// > We load the DTO with the calculation of the token returned by the method...
// ..."GenerateJwtToken" <
result = this.Ok(new AuthenticateUserDto()
{
Login = user.Email,
Name = user.UserName,
Token = this. GenerateJwtToken(user),
});
}

37

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

else
{
StringBuilder sb = new StringBuilder();
// > Identification of the message code <
sb.Append("JWT_ERR_LOGIN_A1 - Invalid email address or password");
result = this.BadRequest(new AuthenticateUserDto()
{
Login = user.Email,
Name = user.UserName,
// > Calls the "GenerateJwtToke" method, which is responsible for...
// ...calculating a new Token <
Token = null,
ErrorMsge = sb.ToString()
});
}
}
// > We return the result <
return result;
}

38

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

X The “DynamicResponseController” controller


X-A Added the “[Authorize]” attribute

The attribute “[Authorize(AuthenticationSchemes =JwtBearerDefaults.AuthenticationScheme)]” will


allow the validity of the transmitted Token to be checked.

39

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

XI Improve the configuration….


XI-A Create a “SecurityOptions” class to store the Token calculation key

In the “API.Response.Dynamic.Model.Infrastructures”
project, add the “Configurations” folder (1).

• In the "Configurations" folder, right-click and select "Add" (2).

• Then select "New Item" (3).

40

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

➢ Select "Class" (1),


➢ Name the class "SecurityOptions" (2),
➢ Confirm with "Add" (3)

➢ Add the "key" property.

➢ Be careful, the syntax and capitalization must


be the same as those in "appsettings.json.").

41

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

➢ The syntax of the “key” member of the “SecurityOptions” class


must be identical to the syntax of the “key” section of the “Jwt”
section.

42

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

XI-B Modify the "AddCustomAuthentication" method of the


"SecurityMethods" class

Retrieving the Token calculation key by binding.

43

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

XII Test authentication with swagger


XII-A Configure Swagger in the “Program.cs” class for Token input
XII-A-1 What we want to achieve

44

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

45

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

Note: you must click on the


“Authorize” button (1)

(1) Click on "Authorize",


(2) Enter "Bearer" + paste the Token copied above (note: leave a " " after "Bearer"),
(3) Click on "Authorize"

Click on “Close” to finish.

46

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

The call to the action (here "DynamicReques") works with the correct token.
(We're now entering the breakpoint).

47

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net
.Net TIPS JSON Web Authentication (JWT)

XII-A-2 The code to insert into the “Program.cs” class

See also my documentation «TEC_C#_NET_JWT_AUTHENTICATION_ERROR_MESSAGE_FAILED_TO_EXECEUTE.DOC ».

builder.Services.AddSwaggerGen(options =>
{
// > Add a custom operation filter that sets default values <
options.OperationFilter<SwaggerDefaultValues>();

var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name} .xml";


var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);

// > Add JWT Authentication 1/2 <


options.AddSecurityDefinition( "Bearer ", new Microsoft.OpenApi.Models.OpenApiSecurityScheme
{
Description = "JWT Authorization header using Bearer schema.",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey

});

// > Add JWT Authentication 2/2 <


options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer "
},
Scheme = "oauth2" , Name = "Bearer " ,

In = ParameterLocation.Header,
},

new List<string>()

}
});

});

48

Jean-Christophe Cherid / [email protected] [.Net 8 JSON Web Authentication] Windev & C#/.Net

You might also like