Exemplo n.º 1
0
        private async Task <AuthResult> GenerateJwtToken(IdentityUser user)
        {
            var jwtTokenHandler = new JwtSecurityTokenHandler();
            var key             = Encoding.ASCII.GetBytes(_jwtConfig.Secret);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim("Id", user.Id),
                    new Claim(JwtRegisteredClaimNames.Email, user.Email),
                    new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
                }),
                Expires            = DateTime.UtcNow.Add(_jwtConfig.),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token        = jwtTokenHandler.CreateToken(tokenDescriptor);
            var jwtToken     = jwtTokenHandler.WriteToken(token);
            var refreshToken = new RefreshToken()
            {
                JwtID      = token.Id,
                IsUsed     = false,
                UserID     = user.Id,
                AddedDate  = DateTime.UtcNow,
                ExpiryDate = DateTime.Now.AddYears(1),
                IsRevoked  = false,
                Token      = OtherTool.RandomString(25) + Guid.NewGuid()
            };
            await _db.RefreshTokens.AddAsync(refreshToken);

            await _db.SaveChangesAsync();

            return(new AuthResult()
            {
                Token = jwtToken,
                Success = true,
                RefreshToken = refreshToken.Token
            });
        }
Exemplo n.º 2
0
        private async Task <AuthResult> VerifyAndGenerateToken(TokenRequest tokenRequest)
        {
            var jwtTokenHandler = new JwtSecurityTokenHandler();

            try
            {
                // Validation 1 - Validation JWT token format
                var tokenInVerification = jwtTokenHandler.ValidateToken(tokenRequest.Token, _tokenValidationParams, out var validatedToken);
                // Validation 2 - Validate encryption alg
                if (validatedToken is JwtSecurityToken jwtSecurityToken)
                {
                    var result = jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase);

                    if (result == false)
                    {
                        return(null);
                    }
                }
                // Validation 3 - validate expiry date
                var utcExpiryDate = long.Parse(tokenInVerification.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Exp).Value);
                var expiryDate    = OtherTool.UnixTimeStampToDateTime(utcExpiryDate);
                if (expiryDate > DateTime.UtcNow)
                {
                    return(new AuthResult()
                    {
                        Success = false,
                        Errors = new List <string>()
                        {
                            "Token has not yet expired"
                        }
                    });
                }
                // validation 4 - validate existence of the token
                var storedToken = await _db.RefreshTokens.FirstOrDefaultAsync(x => x.Token == tokenRequest.RefreshToken);

                if (storedToken == null)
                {
                    return(new AuthResult()
                    {
                        Success = false,
                        Errors = new List <string>()
                        {
                            "Token does not exist"
                        }
                    });
                }
                // Validation 5 - validate if used
                if (storedToken.IsUsed)
                {
                    return(new AuthResult()
                    {
                        Success = false,
                        Errors = new List <string>()
                        {
                            "Token has been used"
                        }
                    });
                }
                // Validation 6 - validate if revoked
                if (storedToken.IsRevoked)
                {
                    return(new AuthResult()
                    {
                        Success = false,
                        Errors = new List <string>()
                        {
                            "Token has been revoked"
                        }
                    });
                }
                // Validation 7 - validate the id
                var jti = tokenInVerification.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Jti).Value;

                if (storedToken.JwtID != jti)
                {
                    return(new AuthResult()
                    {
                        Success = false,
                        Errors = new List <string>()
                        {
                            "Token doesn't match"
                        }
                    });
                }
                // update current token
                storedToken.IsUsed = true;
                _db.RefreshTokens.Update(storedToken);
                await _db.SaveChangesAsync();

                // Generate a new token
                var dbUser = await _userManager.FindByIdAsync(storedToken.UserID);

                return(await GenerateJwtToken(dbUser));
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Lifetime validation failed. The token is expired."))
                {
                    return(new AuthResult()
                    {
                        Success = false,
                        Errors = new List <string>()
                        {
                            "Token has expired please re-login"
                        }
                    });
                }
                else
                {
                    return(new AuthResult()
                    {
                        Success = false,
                        Errors = new List <string>()
                        {
                            "Something went wrong."
                        }
                    });
                }
            }
        }