otkalce

Authentication - generate JWT for user

Mar 10th, 2023
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
CSS 4.00 KB | Source Code | 0 0
  1. // *** Request model ***
  2.     public class JwtTokensRequest
  3.     {
  4.         public string Username { get; set; }
  5.         public string Password { get; set; }
  6.     }
  7.  
  8. // *** New user repository handlers ***
  9.         private bool Authenticate(string username, string password)
  10.         {
  11.             var target = _users.Single(x => x.Username == username);
  12.  
  13.             if (!target.IsConfirmed)
  14.                 return false;
  15.  
  16.             // Get stored salt and hash
  17.             byte[] salt = Convert.FromBase64String(target.PwdSalt);
  18.             byte[] hash = Convert.FromBase64String(target.PwdHash);
  19.  
  20.             byte[] calcHash =
  21.                 KeyDerivation.Pbkdf2(
  22.                     password: password,
  23.                     salt: salt,
  24.                     prf: KeyDerivationPrf.HMACSHA256,
  25.                     iterationCount: 100000,
  26.                     numBytesRequested: 256 / 8);
  27.  
  28.             return hash.SequenceEqual(calcHash);
  29.         }
  30.  
  31.         public Tokens JwtTokens(JwtTokensRequest request)
  32.         {
  33.             var isAuthenticated = Authenticate(request.Username, request.Password);
  34.  
  35.             if (!isAuthenticated)
  36.                 throw new InvalidOperationException("Authentication failed");
  37.  
  38.             // Get secret key bytes
  39.             var jwtKey = _configuration["JWT:Key"];
  40.             var jwtKeyBytes = Encoding.UTF8.GetBytes(jwtKey);
  41.  
  42.             // Create a token descriptor (represents a token, kind of a "template" for token)
  43.             var tokenDescriptor = new SecurityTokenDescriptor
  44.             {
  45.                 Subject = new ClaimsIdentity(new System.Security.Claims.Claim[]
  46.                 {
  47.                     new System.Security.Claims.Claim(ClaimTypes.Name, request.Username),
  48.                     new System.Security.Claims.Claim(JwtRegisteredClaimNames.Sub, request.Username),
  49.                     //new System.Security.Claims.Claim(ClaimTypes.Role, "User")
  50.                 }),
  51.                 Issuer = _configuration["JWT:Issuer"],
  52.                 Audience = _configuration["JWT:Audience"],
  53.                 Expires = DateTime.UtcNow.AddMinutes(10),
  54.                 SigningCredentials = new SigningCredentials(
  55.                     new SymmetricSecurityKey(jwtKeyBytes),
  56.                     SecurityAlgorithms.HmacSha256Signature)
  57.             };
  58.  
  59.             // Create token using that descriptor, serialize it and return it
  60.             var tokenHandler = new JwtSecurityTokenHandler();
  61.             var token = tokenHandler.CreateToken(tokenDescriptor);
  62.             var serializedToken = tokenHandler.WriteToken(token);
  63.  
  64.             return new Tokens
  65.             {
  66.                 Token = serializedToken
  67.             };
  68.         }
  69.  
  70. // *** New controller action to get tokens ***
  71.         [HttpPost("[action]")]
  72.         public ActionResult<Tokens> JwtTokens([FromBody] JwtTokensRequest request)
  73.         {
  74.             try
  75.             {
  76.                 return Ok(_userRepository.JwtTokens(request));
  77.             }
  78.             catch (InvalidOperationException ex)
  79.             {
  80.                 return BadRequest(ex.Message);
  81.             }
  82.         }
  83.  
  84. // *** Configure JWT services: improved configuration ***
  85. builder.Services
  86.     .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  87.     .AddJwtBearer(o => {
  88.         var jwtKey = builder.Configuration["JWT:Key"];
  89.         var jwtKeyBytes = Encoding.UTF8.GetBytes(jwtKey);
  90.         o.TokenValidationParameters = new TokenValidationParameters
  91.         {
  92.             ValidateIssuer = true,
  93.             ValidIssuer = builder.Configuration["JWT:Issuer"],
  94.             ValidateAudience = true,
  95.             ValidAudience = builder.Configuration["JWT:Audience"],
  96.             ValidateIssuerSigningKey = true,
  97.             IssuerSigningKey = new SymmetricSecurityKey(jwtKeyBytes),
  98.             ValidateLifetime = true,
  99.         };
  100.     });
  101.  
  102.   // *** New needed configuration in appsettings.json ***
  103.   "JWT": {
  104.     "Key": "E(H+MbQeThWmZq4t6w9z$C&F)J@NcRfU",
  105.     "Issuer": "localhost",
  106.     "Audience": "localhost"
  107.   }
  108.  
Tags: jwt-token
Add Comment
Please, Sign In to add comment