// revoke refresh token only if it belongs to client doing the request private async Task <bool> RevokeRefreshTokenAsync(string handle, Client client) { var token = await _grants.GetRefreshTokenAsync(handle); if (token != null) { if (token.ClientId == client.ClientId) { _logger.LogDebug("Refresh token revoked"); await _grants.RemoveRefreshTokensAsync(token.SubjectId, token.ClientId); await _grants.RemoveReferenceTokensAsync(token.SubjectId, token.ClientId); } else { var message = string.Format("Client {clientId} tried to revoke a refresh token belonging to a different client: {clientId}", client.ClientId, token.ClientId); _logger.LogWarning(message); await RaiseFailureEventAsync(message); } return(true); } return(false); }
private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters) { _logger.LogDebug("Start validation of refresh token request"); var refreshTokenHandle = parameters.Get(OidcConstants.TokenRequest.RefreshToken); if (refreshTokenHandle.IsMissing()) { var error = "Refresh token is missing"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(null, error); return(Invalid(OidcConstants.TokenErrors.InvalidRequest)); } if (refreshTokenHandle.Length > _options.InputLengthRestrictions.RefreshToken) { var error = "Refresh token too long"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(null, error); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.RefreshTokenHandle = refreshTokenHandle; ///////////////////////////////////////////// // check if refresh token is valid ///////////////////////////////////////////// var refreshToken = await _grants.GetRefreshTokenAsync(refreshTokenHandle); if (refreshToken == null) { LogError("Refresh token cannot be found in store: {refreshToken}", refreshTokenHandle); var error = "Refresh token cannot be found in store: " + refreshTokenHandle; await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if refresh token has expired ///////////////////////////////////////////// if (refreshToken.CreationTime.HasExceeded(refreshToken.Lifetime)) { var error = "Refresh token has expired"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); await _grants.RemoveRefreshTokenAsync(refreshTokenHandle); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if client belongs to requested refresh token ///////////////////////////////////////////// if (_validatedRequest.Client.ClientId != refreshToken.ClientId) { LogError("{clientId} tries to refresh token belonging to {clientId}", _validatedRequest.Client.ClientId, refreshToken.ClientId); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if client still has offline_access scope ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowAccessToAllScopes) { if (!_validatedRequest.Client.AllowedScopes.Contains(Constants.StandardScopes.OfflineAccess)) { LogError("{clientId} does not have access to offline_access scope anymore", _validatedRequest.Client.ClientId); var error = "Client does not have access to offline_access scope anymore"; await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } } _validatedRequest.RefreshToken = refreshToken; ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var subject = _validatedRequest.RefreshToken.Subject; var isActiveCtx = new IsActiveContext(subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.RefreshTokenValidation); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { LogError("{subjectId} has been disabled", _validatedRequest.RefreshToken.SubjectId); var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId; await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.Subject = subject; _logger.LogDebug("Validation of refresh token request success"); return(Valid()); }