public string EncodeRefreshToken(string username, DateTime expiryDate) { var user = Read(username); var previousTokens = _dbContext.RefreshToken .Where(token => token.UserId == user.UserId && !token.IsRevoked) .ToList(); foreach (var token in previousTokens) { token.IsRevoked = true; } var refreshToken = new RefreshToken { UserId = user.UserId, RefreshTokenExpiryDate = expiryDate, InitialVector = PasswordHelper.GenerateInitialVector(), EncryptionKey = PasswordHelper.GenerateAesKey(), }; var refreshTokenEntity = _dbContext.RefreshToken.Add(refreshToken).Entity; _dbContext.RefreshToken.UpdateRange(previousTokens); _dbContext.SaveChanges(); var refreshTokenClaims = new DecodedRefreshTokenClaims { Username = username, ExpiryDate = expiryDate, Secret = _dataProtector.Protect(BitConverter.GetBytes(refreshToken.RefreshTokenId)), }; var encodedToken = String.Empty; using (var serializerStream = new MemoryStream()) { Console.WriteLine($"{nameof(EncodeRefreshToken)} refreshTokenClaims: [{refreshTokenClaims.ToString()}]"); _binaryFormatter.Serialize(serializerStream, refreshTokenClaims); encodedToken = Convert.ToBase64String(serializerStream.ToArray()); } return(encodedToken); }
public bool ValidateRefreshToken(string encodedRefreshToken, out DecodedRefreshTokenClaims refreshTokenClaims, out User user) { using (var deserializerStream = new MemoryStream(Convert.FromBase64String(encodedRefreshToken))) { refreshTokenClaims = (DecodedRefreshTokenClaims)_binaryFormatter.Deserialize(deserializerStream); user = null; if (refreshTokenClaims.ExpiryDate < DateTime.Now) { return(false); } var username = refreshTokenClaims.Username; var activeToken = _dbContext.RefreshToken .Include(rt => rt.User) .Where(rt => rt.User.Username == username && !rt.IsRevoked) .FirstOrDefault(); user = activeToken.User; if (activeToken == null) { return(false); } Console.WriteLine($"{nameof(ValidateRefreshToken)} refreshTokenClaims: [{refreshTokenClaims}]"); Console.WriteLine($"{nameof(ValidateRefreshToken)} EncryptionKey: [{BitConverter.ToString(activeToken.EncryptionKey)}], InitialVector: [{BitConverter.ToString(activeToken.InitialVector)}]"); var decryptedBytes = _dataProtector.Unprotect(refreshTokenClaims.Secret); var decryptedSecret = BitConverter.ToInt64(decryptedBytes); Console.WriteLine($"{nameof(ValidateRefreshToken)} ActiveRefreshTokenId: {activeToken.RefreshTokenId}, DecryptedTokenId: {decryptedSecret}"); if (activeToken.RefreshTokenId == decryptedSecret) { return(true); } } return(false); }