public async Task <TokenResultDto> Prepare(ClaimsIdentity identity, string username) { try { var now = DateTime.UtcNow; /* Specifically add the jti (nonce), iat (issued timestamp), and sub (subject/user) claims. * You can add other claims here, if you want: */ var claims = identity.Claims?.ToList() ?? new List <Claim>(); claims.AddRange(new[] { new Claim(JwtRegisteredClaimNames.Sub, username), new Claim(JwtRegisteredClaimNames.Jti, await _options.NonceGenerator()), new Claim(JwtRegisteredClaimNames.Iat, JwtHelper.ToUnixEpochDate(now).ToString(), ClaimValueTypes.Integer64), }); // Create the JWT and write it to a string var jwt = new JwtSecurityToken( issuer: _options.Issuer, audience: _options.Audience, claims: claims.ToArray(), notBefore: now, expires: now.Add(_options.Expiration), signingCredentials: _options.SigningCredentials); var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); var response = new TokenResultDto { Token = encodedJwt, ExpiresIn = (int)_options.Expiration.TotalSeconds, }; return(response); } catch (Exception ex) { _logger.LogError(ex, $"Unable to create JWT token: {ex.Message}"); throw; } }
private async Task GenerateToken(HttpContext context) { var username = context.Request.Form["username"]; var password = context.Request.Form["password"]; var identity = await _options.IdentityResolver(username, password); if (identity == null) { context.Response.StatusCode = 400; await context.Response.WriteAsync("Invalid username or password.", new CancellationToken()); return; } else { TokenResultDto response = await _jwtService.Prepare(identity, username); // Serialize and return the response context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonConvert.SerializeObject(response, _serializerSettings), new CancellationToken()); } }