private void ValidateRefreshToken(DbRefreshToken refreshToken, ClaimsPrincipal claimsIdentity) { var jti = claimsIdentity.Claims.Single(c => c.Type == JwtRegisteredClaimNames.Jti).Value; var userId = claimsIdentity.Claims.Single(c => c.Type == "id").Value; if (refreshToken is null) { throw new RefreshTokenNotFoundException(); } if (DateTime.UtcNow > refreshToken.ExpiryDate) { throw new RefreshTokenExpiredException(); } if (refreshToken.Used) { throw new InvalidTokenException("This token has already been used."); } if (refreshToken.JwtId != jti) { throw new RefreshTokenConflictException(); } }
public async Task <RefreshToken> GetRefreshToken(string token) { try { using (var connection = await GetConnectionAsync()) { var res = await connection.QueryAsync(RegistrarQueries.RefreshTokenSelect, new { Token = token }); if (!res.Any()) { throw new RecordNotFoundException(); } var dbModel = new DbRefreshToken(res.First()); return(dbModel.ToModel()); } } catch (Exception e) { if (e is RecordNotFoundException) { throw; } throw new Exception("Could not get Refresh Token"); } }
public IActionResult Refresh([FromQuery] UserTokenRefreshModel userRefreshModel) { _logger.LogTrace("Update session attempt from {RemoteIp} and {UserAgent} with refresh token {RefreshToken}", UserIp, UserAgent, userRefreshModel.RefreshToken); var dbToken = _db.RefreshTokens .Include(rt => rt.NavUser) .FirstOrDefault(rt => rt.Token == userRefreshModel.RefreshToken); if (dbToken == null) { _logger.LogTrace("Invalid refresh token. Need re:login"); ModelState.AddModelError("RefreshToken", "Invalid refresh token"); return(BadRequest(new ValidationProblemDetails(ModelState))); } dbToken.UsedDateTime = _now; dbToken.UsedIp = UserIp; var dbUser = dbToken.NavUser; var newRefreshToken = new DbRefreshToken() { Fingerprint = userRefreshModel.Fingerprint, FromTime = _now, ToTime = _now.AddDays(_authOptions.RefreshTokenLifetimeDays), CreatedIp = UserIp, NavUser = dbUser, UserAgent = UserAgent, Token = _rngGenerator.GetGuid() }; try { _db.RefreshTokens.Add(newRefreshToken); _db.RefreshTokens.Update(dbToken); _db.SaveChanges(); var jwt = _tokenGenerator.GenerateToken(dbUser.UserName, dbUser.Role); _logger.LogDebug("Old tokens expired, new created ({RefreshToken}) and JWT generated for user: {UserName}", newRefreshToken.Token, dbUser.UserName); return(Ok(new AuthResult() { JwtToken = jwt, UserName = dbUser.UserName, RefreshToken = newRefreshToken.Token })); } catch (SecurityTokenEncryptionFailedException e) { _logger.LogError(e, "Problem with generating JWT for {UserName}", dbUser.UserName); throw; } catch (Exception e) { _logger.LogError(e, "Problem with applying changes to db"); throw; } }
public async Task UpdateRefreshToken(RefreshToken token) { try { var dbModel = new DbRefreshToken(token); using (var connection = await GetConnectionAsync()) { await connection.ExecuteAsync(RegistrarQueries.RefreshTokenUpdate, dbModel); } } catch (Exception e) { if (e is RecordNotFoundException) { throw; } throw new Exception("Could not update Refresh Token"); } }
private async Task <AuthenticationResult> GenerateAuthenticationResultForUserAsync(IdentityUser user) { var tokenHandler = new JwtSecurityTokenHandler(); var token = this.GenerateJwtToken(user); var refreshToken = new DbRefreshToken { Token = this.GenerateRefreshToken(), JwtId = token.Id, UserId = user.Id, CreationDate = DateTime.UtcNow, ExpiryDate = DateTime.UtcNow.AddDays(10), }; await this.identityContext.RefreshTokens.AddAsync(refreshToken); await this.identityContext.SaveChangesAsync(); return(new AuthenticationResult { Success = true, Token = tokenHandler.WriteToken(token), RefreshToken = refreshToken.Token, }); }
public IActionResult Login([FromQuery] UserLoginModel loginModel) { _logger.LogTrace("Login attempt from {RemoteIp} and {UserAgent} with user name {UserName}", UserIp, UserAgent, loginModel.UserName); var dbUser = _db.Users.FirstOrDefault(u => u.UserName == loginModel.UserName); if (dbUser == null) { //TODO: maybe change to generalized error _logger.LogTrace("User name {UserName} not exist", loginModel.UserName); ModelState.AddModelError("User", "user not found"); return(BadRequest(new ValidationProblemDetails(ModelState))); } try { if (dbUser.State == EUserState.InChallenge) { return(Forbid(new AuthenticationProperties(new Dictionary <string, string> { { "Challenge", "need pass" } }))); } switch (dbUser.VerifyPassword(loginModel.Password)) { case PasswordVerificationResult.Failed: _logger.LogTrace("User {UserName} send wrong password", loginModel.UserName); ModelState.AddModelError("Password", "Wrong password"); return(BadRequest(new ValidationProblemDetails(ModelState))); case PasswordVerificationResult.SuccessRehashNeeded: { dbUser.HashPasswordAndSet(loginModel.Password); _db.Users.Update(dbUser); break; } } var refreshToken = new DbRefreshToken() { Fingerprint = loginModel.Fingerprint, FromTime = _now, ToTime = _now.AddDays(_authOptions.RefreshTokenLifetimeDays), CreatedIp = UserIp, NavUser = dbUser, UserAgent = UserAgent, Token = _rngGenerator.GetGuid() }; _db.RefreshTokens.Add(refreshToken); _db.SaveChanges(); var jwt = _tokenGenerator.GenerateToken(dbUser.UserName, dbUser.Role); return(Ok(new AuthResult() { JwtToken = jwt, RefreshToken = refreshToken.Token, UserName = dbUser.UserName })); } catch (SecurityTokenEncryptionFailedException e) { _logger.LogError(e, "Problem with generating JWT for {UserName}", dbUser.UserName); throw; } catch (Exception e) { _logger.LogError(e, "Problem with applying changes to db"); throw; } }