Implementing Microservice Architecture In .NET Part 2 , Auth Service by JWT Token

Reza Mansouri
4 min readNov 23, 2022

--

Hello evryone :)

Last Article:

Implementing Microservice Architecture In .NET Part 1 , Project Overview

at the last article we see the schema of our microservice

in this section , we develop Auth Microservice that do authentication and authorization of our microservice.

In this article, I will not explain the codes line by line, we will review the main operations together.

For this oprations we can use OpenID Connect and OAuth like Duende IdentityServer for authentication and authorization in microservice but in this case we just use jwt token.

how? well , jwt token can have all data that we need , save our requiment information in jwt token ( like username , userid , roles and etc) and send it in header request to other microservices , target microservice read the jwt token and find user info and the role that user have , that is simple.

you can see we create jwt token base on information ( claims ) that we need like this

and created token like this

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOiJiOTAyYjRkMS00MmY0LTRlZjMtYmZkNi01NTc5MWVlOGIyZTkiLCJVc2VyTmFtZSI6IlJlemEgTWFuc291cmkiLCJSb2xlcyI6IlVzZXIiLCJMb2dpbkRhdGUiOiIwMi8wOS8xNDAxIDEwOjAxOjAwINioLti4IiwiRXhwaXJlRGF0ZSI6IjAzLzA5LzE0MDEgMTA6MDE6MDAg2Kgu2LgiLCJuYmYiOjE2NjkyMjgyNjAsImV4cCI6MTcwMDc2NDI2MCwiaWF0IjoxNjY5MjI4MjYwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcxNDciLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjcxNDcifQ.gNU2S2Q6j6vjZj3GCzoXXIxKk5dL4lXdwvLywwb2LN8

it is decoded token by Jwt.io

for this way , we first need to save user by Register Action , we add one action call register to save user data in database by User Service

public User Register(AddUserDto addUserModel)
{

var hashpassword = Security.SecurePasswordHasher.Hash(addUserModel.Password);

var user = new User()
{
UserID = Guid.NewGuid(),
Mobile = addUserModel.Mobile,
Name = addUserModel.Name,
Password = hashpassword,
Roles = "User",
CreatedDate = DateTime.Now,
IsActive = true

};
context.Users.Add(user);
context.SaveChanges();
return user;
}

we save user info by register action and save in database

of course do not forget to hash password before save it in database.

after we add user , we can login by mobile ( in this case it is our username ) and password by CanLogin method in our UserService.

 public bool CanLogin(LoginUserDto loginModel)
{
var user = context.Users.FirstOrDefault(x => x.Mobile == loginModel.Mobile);
if (user != null)
{
return Security.SecurePasswordHasher.Verify(loginModel.Password, user.Password);
}
return false;
}

if the login was successfully we create jwt token by the user information that we need . we call TokenManagerService.CreateToken and send our need user data in input parameter to create token

if (_userService.CanLogin(login))
{

var tokenString = TokenManagerService.CreateToken(_userService.GetUserClaim(login.Mobile));
return Ok(new { token = tokenString , status = true });
}

and finaly create token

 public static string CreateToken(Dictionary<string, object> keyValues)
{

DateTime issuedAt = DateTime.UtcNow;
DateTime expires = DateTime.UtcNow.AddYears(1);
var tokenHandler = new JwtSecurityTokenHandler();
ClaimsIdentity claimsIdentity = new ClaimsIdentity();// new[]
foreach (var key in keyValues)
{
claimsIdentity.AddClaim(new Claim(key.Key, key.Value.ToString()));
}
const string sec = "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1";
var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
var token = tokenHandler.CreateJwtSecurityToken(
issuer: "http://localhost:7147",
audience: "http://localhost:7147",
subject: claimsIdentity,
notBefore: issuedAt,
expires: expires,
signingCredentials: signingCredentials);
var tokenString = tokenHandler.WriteToken(token);
tokenString = EncryptionHelper.Encrypt(tokenString);

return tokenString;

}

it’s better to encrypt token data before send it to clients , because the token data can be edited , if we save token in the storage like cookie in our client app , user can see it and change it , but if we encrypt token and decrypt it when we want to get user data , then has no way to find out token data by user

EncryptionHelper.Encrypt(tokenString);

finally We have two main action in our AuthController , Register user And Login.

we call actions by swagger to see result

Register : Send user data and save information in database

Login : Send mobile ( username ) and password and get encrypted token

after that we have token and can send it in header of our request ( its our contract ) then the request received by target microservice , by token it can authorize user info .

we can see this operation in next articles when developing ProductMicroservice .

I hope you like this article :)

Next Article :

Implementing Microservice Architecture In .NET Part 3 , Product Service

--

--