async public Task IsActiveAsync(IsActiveContext context) { var subject = context.Subject; if (subject == null) throw new ArgumentNullException(nameof(context.Subject)); var subjectId = subject.GetSubjectId(); var user = await _userManager.FindByIdAsync(subjectId); context.IsActive = false; if (user != null) { if (_userManager.SupportsUserSecurityStamp) { var security_stamp = subject.Claims.Where(c => c.Type == "security_stamp").Select(c => c.Value).SingleOrDefault(); if (security_stamp != null) { var db_security_stamp = await _userManager.GetSecurityStampAsync(user); if (db_security_stamp != security_stamp) return; } } context.IsActive = !user.LockoutEnabled || !user.LockoutEnd.HasValue || user.LockoutEnd <= DateTime.Now; } }
private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters) { Logger.Info("Start validation of refresh token request"); var refreshTokenHandle = parameters.Get(Constants.TokenRequest.RefreshToken); if (refreshTokenHandle.IsMissing()) { var error = "Refresh token is missing"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(null, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } _validatedRequest.RefreshTokenHandle = refreshTokenHandle; ///////////////////////////////////////////// // check if refresh token is valid ///////////////////////////////////////////// var refreshToken = await _refreshTokens.GetAsync(refreshTokenHandle); if (refreshToken == null) { var error = "Refresh token is invalid"; LogWarn(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if refresh token has expired ///////////////////////////////////////////// if (refreshToken.CreationTime.HasExceeded(refreshToken.LifeTime)) { var error = "Refresh token has expired"; LogWarn(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); await _refreshTokens.RemoveAsync(refreshTokenHandle); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if client belongs to requested refresh token ///////////////////////////////////////////// if (_validatedRequest.Client.ClientId != refreshToken.ClientId) { LogError(string.Format("Client {0} tries to refresh token belonging to client {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId)); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if client still has offline_access scope ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowAccessToAllScopes) { if (!_validatedRequest.Client.AllowedScopes.Contains(Constants.StandardScopes.OfflineAccess)) { var error = "Client does not have access to offline_access scope anymore"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } } _validatedRequest.RefreshToken = refreshToken; ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var principal = IdentityServerPrincipal.FromSubjectId(_validatedRequest.RefreshToken.SubjectId, refreshToken.AccessToken.Claims); var isActiveCtx = new IsActiveContext(principal, _validatedRequest.Client); await _users.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } Logger.Info("Validation of refresh token request success"); return(Valid()); }
public async Task IsActiveAsync(IsActiveContext context) { var subjectId = context.Subject.GetSubjectId(); context.IsActive = await _localUserService.IsUserActive(subjectId); }
/// <summary> /// Validates the device code. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> public async Task ValidateAsync(DeviceCodeValidationContext context) { var deviceCode = await _devices.FindByDeviceCodeAsync(context.DeviceCode); if (deviceCode == null) { _logger.LogError("Invalid device code"); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant); return; } // validate client binding if (deviceCode.ClientId != context.Request.Client.ClientId) { _logger.LogError("Client {0} is trying to use a device code from client {1}", context.Request.Client.ClientId, deviceCode.ClientId); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant); return; } if (await _throttlingService.ShouldSlowDown(context.DeviceCode, deviceCode)) { _logger.LogError("Client {0} is polling too fast", deviceCode.ClientId); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.SlowDown); return; } // validate lifetime if (deviceCode.CreationTime.AddSeconds(deviceCode.Lifetime) < _systemClock.UtcNow) { _logger.LogError("Expired device code"); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.ExpiredToken); return; } // denied if (deviceCode.IsAuthorized && (deviceCode.AuthorizedScopes == null || deviceCode.AuthorizedScopes.Any() == false)) { _logger.LogError("No scopes authorized for device authorization. Access denied"); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AccessDenied); return; } // make sure code is authorized if (!deviceCode.IsAuthorized || deviceCode.Subject == null) { context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AuthorizationPending); return; } // make sure user is enabled var isActiveCtx = new IsActiveContext(deviceCode.Subject, context.Request.Client, IdentityServerConstants.ProfileIsActiveCallers.DeviceCodeValidation); await _profile.IsActiveAsync(isActiveCtx); if (!isActiveCtx.IsActive) { _logger.LogError("User has been disabled: {subjectId}", deviceCode.Subject.GetSubjectId()); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant); return; } context.Request.DeviceCode = deviceCode; context.Request.SessionId = deviceCode.SessionId; context.Result = new TokenRequestValidationResult(context.Request); await _devices.RemoveByDeviceCodeAsync(context.DeviceCode); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <returns></returns> public Task IsActiveAsync(IsActiveContext context) { // check already done during validation return(Task.CompletedTask); }
private async Task <TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters) { Logger.Info("Start validation of refresh token request"); var refreshTokenHandle = parameters.Get(Constants.TokenRequest.RefreshToken); if (refreshTokenHandle.IsMissing()) { var error = "Refresh token is missing"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(null, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } if (refreshTokenHandle.Length > _options.InputLengthRestrictions.RefreshToken) { var error = "Refresh token too long"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(null, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.RefreshTokenHandle = refreshTokenHandle; ///////////////////////////////////////////// // check if refresh token is valid ///////////////////////////////////////////// var refreshToken = await _refreshTokens.GetAsync(refreshTokenHandle); if (refreshToken == null) { var error = "Refresh token is invalid"; LogWarn(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if refresh token has expired ///////////////////////////////////////////// if (refreshToken.CreationTime.HasExceeded(refreshToken.LifeTime)) { var error = "Refresh token has expired"; LogWarn(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); await _refreshTokens.RemoveAsync(refreshTokenHandle); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if client belongs to requested refresh token ///////////////////////////////////////////// if (_validatedRequest.Client.ClientId != refreshToken.ClientId) { LogError(string.Format("Client {0} tries to refresh token belonging to client {1}", _validatedRequest.Client.ClientId, refreshToken.ClientId)); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, "Invalid client binding"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if client still has offline_access scope ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowAccessToAllScopes) { if (!_validatedRequest.Client.AllowedScopes.Contains(Constants.StandardScopes.OfflineAccess)) { var error = "Client does not have access to offline_access scope anymore"; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } } ///////////////////////////////////////////// // check if client still has access to // all scopes from the original token request ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowAccessToAllScopes) { foreach (var scope in refreshToken.Scopes) { if (!_validatedRequest.Client.AllowedScopes.Contains(scope)) { var error = "Client does not have access to a requested scope anymore: " + scope; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } } } _validatedRequest.RefreshToken = refreshToken; ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var principal = IdentityServerPrincipal.FromSubjectId(_validatedRequest.RefreshToken.SubjectId, refreshToken.AccessToken.Claims); var isActiveCtx = new IsActiveContext(principal, _validatedRequest.Client); await _users.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { var error = "User has been disabled: " + _validatedRequest.RefreshToken.SubjectId; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } ///////////////////////////////////////////// // validate token type and PoP parameters if pop token is requested ///////////////////////////////////////////// var tokenType = parameters.Get("token_type"); if (tokenType != null && tokenType == "pop") { var result = ValidatePopParameters(parameters); if (result.IsError) { var error = "PoP parameter validation failed: " + result.ErrorDescription; LogError(error); await RaiseRefreshTokenRefreshFailureEventAsync(refreshTokenHandle, error); return(Invalid(result.Error, result.ErrorDescription)); } else { _validatedRequest.RequestedTokenType = RequestedTokenTypes.PoP; } } Logger.Info("Validation of refresh token request success"); return(Valid()); }
public Task IsActiveAsync(IsActiveContext context) { context.IsActive = true; return(Task.FromResult(true)); }
public override Task IsActiveAsync(IsActiveContext context) { return(base.IsActiveAsync(context)); }
public Task IsActiveAsync(IsActiveContext context) => Task.CompletedTask;
public virtual async Task IsActiveAsync(IsActiveContext context) { var user = await GetUser(context.Subject); context.IsActive = !_options.RequireConfirmedEmail || (user?.EmailConfirmed ?? false); }
public async Task IsActiveAsync(IsActiveContext context) { var user = await _userManager.GetUserAsync(context.Subject); context.IsActive = user != null; }
private async Task <TokenRequestValidationResult> ValidateExtensionGrantRequestAsync(NameValueCollection parameters) { _logger.LogDebug("Start validation of custom grant token request"); ///////////////////////////////////////////// // check if client is allowed to use grant type ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowedGrantTypes.Contains(_validatedRequest.GrantType)) { LogError("Client does not have the custom grant type in the allowed list, therefore requested grant is not allowed", new { clientId = _validatedRequest.Client.ClientId }); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType)); } ///////////////////////////////////////////// // check if a validator is registered for the grant type ///////////////////////////////////////////// if (!_extensionGrantValidator.GetAvailableGrantTypes().Contains(_validatedRequest.GrantType, StringComparer.Ordinal)) { LogError("No validator is registered for the grant type", new { grantType = _validatedRequest.GrantType }); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType)); } ///////////////////////////////////////////// // check if client is allowed to request scopes ///////////////////////////////////////////// if (!await ValidateRequestedScopesAsync(parameters)) { return(Invalid(OidcConstants.TokenErrors.InvalidScope)); } ///////////////////////////////////////////// // validate custom grant type ///////////////////////////////////////////// var result = await _extensionGrantValidator.ValidateAsync(_validatedRequest); if (result == null) { LogError("Invalid extension grant"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } if (result.IsError) { if (result.Error.IsPresent()) { LogError("Invalid extension grant", new { error = result.Error }); return(Invalid(result.Error, result.ErrorDescription, result.CustomResponse)); } else { LogError("Invalid extension grant"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant, customResponse: result.CustomResponse)); } } if (result.Subject != null) { ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext( result.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.ExtensionGrantValidation); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { // todo: raise event? LogError("User has been disabled", new { subjectId = result.Subject.GetSubjectId() }); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.Subject = result.Subject; } _logger.LogDebug("Validation of extension grant token request success"); return(Valid(result.CustomResponse)); }
private async Task <TokenRequestValidationResult> ValidateResourceOwnerCredentialRequestAsync(NameValueCollection parameters) { _logger.LogDebug("Start resource owner password token request validation"); ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowedGrantTypes.Contains(GrantType.ResourceOwnerPassword)) { LogError("Client not authorized for resource owner flow, check the AllowedGrantTypes setting", new { client_id = _validatedRequest.Client.ClientId }); return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // check if client is allowed to request scopes ///////////////////////////////////////////// if (!(await ValidateRequestedScopesAsync(parameters))) { return(Invalid(OidcConstants.TokenErrors.InvalidScope)); } ///////////////////////////////////////////// // check resource owner credentials ///////////////////////////////////////////// var userName = parameters.Get(OidcConstants.TokenRequest.UserName); var password = parameters.Get(OidcConstants.TokenRequest.Password); if (userName.IsMissing()) { LogError("Username is missing"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } if (password.IsMissing()) { password = ""; } if (userName.Length > _options.InputLengthRestrictions.UserName || password.Length > _options.InputLengthRestrictions.Password) { LogError("Username or password too long"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.UserName = userName; ///////////////////////////////////////////// // authenticate user ///////////////////////////////////////////// var resourceOwnerContext = new ResourceOwnerPasswordValidationContext { UserName = userName, Password = password, Request = _validatedRequest }; await _resourceOwnerValidator.ValidateAsync(resourceOwnerContext); if (resourceOwnerContext.Result.IsError) { // protect against bad validator implementations resourceOwnerContext.Result.Error ??= OidcConstants.TokenErrors.InvalidGrant; if (resourceOwnerContext.Result.Error == OidcConstants.TokenErrors.UnsupportedGrantType) { LogError("Resource owner password credential grant type not supported"); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, "password grant type not supported", resourceOwnerContext.Request.Client.ClientId); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType, customResponse: resourceOwnerContext.Result.CustomResponse)); } var errorDescription = "invalid_username_or_password"; if (resourceOwnerContext.Result.ErrorDescription.IsPresent()) { errorDescription = resourceOwnerContext.Result.ErrorDescription; } LogInformation("User authentication failed: ", errorDescription ?? resourceOwnerContext.Result.Error); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, errorDescription, resourceOwnerContext.Request.Client.ClientId); return(Invalid(resourceOwnerContext.Result.Error, errorDescription, resourceOwnerContext.Result.CustomResponse)); } if (resourceOwnerContext.Result.Subject == null) { var error = "User authentication failed: no principal returned"; LogError(error); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, error, resourceOwnerContext.Request.Client.ClientId); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext(resourceOwnerContext.Result.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.ResourceOwnerValidation); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { LogError("User has been disabled", new { subjectId = resourceOwnerContext.Result.Subject.GetSubjectId() }); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, "user is inactive", resourceOwnerContext.Request.Client.ClientId); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.UserName = userName; _validatedRequest.Subject = resourceOwnerContext.Result.Subject; await RaiseSuccessfulResourceOwnerAuthenticationEventAsync(userName, resourceOwnerContext.Result.Subject.GetSubjectId(), resourceOwnerContext.Request.Client.ClientId); _logger.LogDebug("Resource owner password token request validation success."); return(Valid(resourceOwnerContext.Result.CustomResponse)); }
private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters) { _logger.LogDebug("Start validation of authorization code token request"); ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (!_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.AuthorizationCode) && !_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.Hybrid)) { LogError("Client not authorized for code flow"); return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate authorization code ///////////////////////////////////////////// var code = parameters.Get(OidcConstants.TokenRequest.Code); if (code.IsMissing()) { LogError("Authorization code is missing"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } if (code.Length > _options.InputLengthRestrictions.AuthorizationCode) { LogError("Authorization code is too long"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCodeHandle = code; var authZcode = await _authorizationCodeStore.GetAuthorizationCodeAsync(code); if (authZcode == null) { LogError("Invalid authorization code", new { code }); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } await _authorizationCodeStore.RemoveAuthorizationCodeAsync(code); if (authZcode.CreationTime.HasExceeded(authZcode.Lifetime, _clock.UtcNow.UtcDateTime)) { LogError("Authorization code expired", new { code }); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // populate session id ///////////////////////////////////////////// if (authZcode.SessionId.IsPresent()) { _validatedRequest.SessionId = authZcode.SessionId; } ///////////////////////////////////////////// // validate client binding ///////////////////////////////////////////// if (authZcode.ClientId != _validatedRequest.Client.ClientId) { LogError("Client is trying to use a code from a different client", new { clientId = _validatedRequest.Client.ClientId, codeClient = authZcode.ClientId }); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // validate code expiration ///////////////////////////////////////////// if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime, _clock.UtcNow.UtcDateTime)) { LogError("Authorization code is expired"); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCode = authZcode; _validatedRequest.Subject = authZcode.Subject; ///////////////////////////////////////////// // validate redirect_uri ///////////////////////////////////////////// var redirectUri = parameters.Get(OidcConstants.TokenRequest.RedirectUri); if (redirectUri.IsMissing()) { LogError("Redirect URI is missing"); return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient)); } if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false) { LogError("Invalid redirect_uri", new { redirectUri, expectedRedirectUri = _validatedRequest.AuthorizationCode.RedirectUri }); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // validate scopes are present ///////////////////////////////////////////// if (_validatedRequest.AuthorizationCode.RequestedScopes == null || !_validatedRequest.AuthorizationCode.RequestedScopes.Any()) { LogError("Authorization code has no associated scopes"); return(Invalid(OidcConstants.TokenErrors.InvalidRequest)); } ///////////////////////////////////////////// // validate PKCE parameters ///////////////////////////////////////////// var codeVerifier = parameters.Get(OidcConstants.TokenRequest.CodeVerifier); if (_validatedRequest.Client.RequirePkce || _validatedRequest.AuthorizationCode.CodeChallenge.IsPresent()) { _logger.LogDebug("Client required a proof key for code exchange. Starting PKCE validation"); var proofKeyResult = ValidateAuthorizationCodeWithProofKeyParameters(codeVerifier, _validatedRequest.AuthorizationCode); if (proofKeyResult.IsError) { return(proofKeyResult); } _validatedRequest.CodeVerifier = codeVerifier; } else { if (codeVerifier.IsPresent()) { LogError("Unexpected code_verifier: {codeVerifier}. This happens when the client is trying to use PKCE, but it is not enabled. Set RequirePkce to true.", codeVerifier); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizationCodeValidation); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { LogError("User has been disabled", new { subjectId = _validatedRequest.AuthorizationCode.Subject.GetSubjectId() }); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _logger.LogDebug("Validation of authorization code token request success"); return(Valid()); }
public Task IsActiveAsync(IsActiveContext context) { context.IsActive = true; return(Task.CompletedTask); // throw new NotImplementedException(); }
/// <inheritdoc/> public async Task ValidateAsync(BackchannelAuthenticationRequestIdValidationContext context) { using var activity = Tracing.BasicActivitySource.StartActivity("BackchannelAuthenticationRequestIdValidator.Validate"); var request = await _backchannelAuthenticationStore.GetByAuthenticationRequestIdAsync(context.AuthenticationRequestId); if (request == null) { _logger.LogError("Invalid authentication request id"); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant); return; } // validate client binding if (request.ClientId != context.Request.Client.ClientId) { _logger.LogError("Client {0} is trying to use a authentication request id from client {1}", context.Request.Client.ClientId, request.ClientId); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant); return; } if (await _throttlingService.ShouldSlowDown(context.AuthenticationRequestId, request)) { _logger.LogError("Client {0} is polling too fast", request.ClientId); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.SlowDown); return; } // validate lifetime if (request.CreationTime.AddSeconds(request.Lifetime) < _systemClock.UtcNow.UtcDateTime) { _logger.LogError("Expired authentication request id"); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.ExpiredToken); return; } // denied if (request.IsComplete && (request.AuthorizedScopes == null || request.AuthorizedScopes.Any() == false)) { _logger.LogError("No scopes authorized for backchannel authentication request. Access denied"); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AccessDenied); await _backchannelAuthenticationStore.RemoveByInternalIdAsync(request.InternalId); return; } // make sure authentication request id is complete if (!request.IsComplete) { context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AuthorizationPending); return; } // make sure user is enabled var isActiveCtx = new IsActiveContext(request.Subject, context.Request.Client, IdentityServerConstants.ProfileIsActiveCallers.BackchannelAuthenticationRequestIdValidation); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { _logger.LogError("User has been disabled: {subjectId}", request.Subject.GetSubjectId()); context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant); return; } context.Request.BackChannelAuthenticationRequest = request; context.Request.Subject = request.Subject; context.Request.SessionId = request.SessionId; context.Result = new TokenRequestValidationResult(context.Request); await _backchannelAuthenticationStore.RemoveByInternalIdAsync(request.InternalId); _logger.LogDebug("Success validating backchannel authentication request id."); }
private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters) { Logger.Info("Start validation of authorization code token request"); ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (Constants.AllowedFlowsForAuthorizationCodeGrantType.Contains(_validatedRequest.Client.Flow) == false) { LogError("Client not authorized for code flow"); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate authorization code ///////////////////////////////////////////// var code = parameters.Get(Constants.TokenRequest.Code); if (code.IsMissing()) { var error = "Authorization code is missing."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } if (code.Length > _options.InputLengthRestrictions.AuthorizationCode) { var error = "Authorization code is too long."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCodeHandle = code; var authZcode = await _authorizationCodes.GetAsync(code); if (authZcode == null) { LogError("Invalid authorization code: " + code); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid handle"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } await _authorizationCodes.RemoveAsync(code); ///////////////////////////////////////////// // populate session id ///////////////////////////////////////////// if (authZcode.SessionId.IsPresent()) { _validatedRequest.SessionId = authZcode.SessionId; } ///////////////////////////////////////////// // validate client binding ///////////////////////////////////////////// if (authZcode.Client.ClientId != _validatedRequest.Client.ClientId) { LogError(string.Format("Client {0} is trying to use a code from client {1}", _validatedRequest.Client.ClientId, authZcode.Client.ClientId)); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid client binding"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // validate PKCE parameters ///////////////////////////////////////////// var codeVerifier = parameters.Get(Constants.TokenRequest.CodeVerifier); if (authZcode.Client.Flow == Flows.AuthorizationCodeWithProofKey || authZcode.Client.Flow == Flows.HybridWithProofKey) { var proofKeyResult = ValidateAuthorizationCodeWithProofKeyParameters(codeVerifier, authZcode); if (proofKeyResult.IsError) { return(proofKeyResult); } _validatedRequest.CodeVerifier = codeVerifier; } else { if (codeVerifier.IsPresent()) { LogError("Unexpected code_verifier with Flow " + authZcode.Client.Flow.ToString()); return(Invalid(Constants.TokenErrors.InvalidGrant)); } } ///////////////////////////////////////////// // validate code expiration ///////////////////////////////////////////// if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime)) { var error = "Authorization code is expired"; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCode = authZcode; ///////////////////////////////////////////// // validate redirect_uri ///////////////////////////////////////////// var redirectUri = parameters.Get(Constants.TokenRequest.RedirectUri); if (redirectUri.IsMissing()) { var error = "Redirect URI is missing."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false) { var error = "Invalid redirect_uri: " + redirectUri; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate scopes are present ///////////////////////////////////////////// if (_validatedRequest.AuthorizationCode.RequestedScopes == null || !_validatedRequest.AuthorizationCode.RequestedScopes.Any()) { var error = "Authorization code has no associated scopes."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client); await _users.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { var error = "User has been disabled: " + _validatedRequest.AuthorizationCode.Subject; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } ///////////////////////////////////////////// // validate token type and PoP parameters if pop token is requested ///////////////////////////////////////////// var tokenType = parameters.Get("token_type"); if (tokenType != null && tokenType == Constants.ResponseTokenTypes.PoP) { var result = ValidatePopParameters(parameters); if (result.IsError) { var error = "PoP parameter validation failed: " + result.ErrorDescription; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(result.Error, result.ErrorDescription)); } else { _validatedRequest.RequestedTokenType = RequestedTokenTypes.PoP; } } Logger.Info("Validation of authorization code token request success"); await RaiseSuccessfulAuthorizationCodeRedeemedEventAsync(); return(Valid()); }
/// <summary> /// Processes the login logic. /// </summary> /// <param name="request">The request.</param> /// <returns></returns> protected internal virtual async Task <InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request) { if (request.PromptMode == OidcConstants.PromptModes.Login || request.PromptMode == OidcConstants.PromptModes.SelectAccount) { // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.RemovePrompt(); _logger.LogInformation("Showing login: request contains prompt={0}", request.PromptMode); return(new InteractionResponse() { IsLogin = true }); } // unauthenticated user var isAuthenticated = request.Subject.IsAuthenticated(); // user de-activated bool isActive = false; if (isAuthenticated) { var isActiveCtx = new IsActiveContext(request.Subject, request.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizeEndpoint); await _profile.IsActiveAsync(isActiveCtx); isActive = isActiveCtx.IsActive; } if (!isAuthenticated || !isActive) { // prompt=none means user must be signed in already if (request.PromptMode == OidcConstants.PromptModes.None) { if (!isAuthenticated) { _logger.LogInformation("Showing error: prompt=none was requested but user is not authenticated"); } else if (!isActive) { _logger.LogInformation("Showing error: prompt=none was requested but user is not active"); } return(new InteractionResponse { Error = OidcConstants.AuthorizeErrors.LoginRequired, }); } if (!isAuthenticated) { _logger.LogInformation("Showing login: User is not authenticated"); } else if (!isActive) { _logger.LogInformation("Showing login: User is not active"); } return(new InteractionResponse() { IsLogin = true }); } // check current idp var currentIdp = request.Subject.GetIdentityProvider(); // check if idp login hint matches current provider var idp = request.GetIdP(); if (idp.IsPresent()) { if (idp != currentIdp) { _logger.LogInformation("Showing login: Current IdP ({idp}) is not the requested IdP ({idp})", currentIdp, idp); return(new InteractionResponse() { IsLogin = true }); } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = request.Subject.GetAuthenticationTime(); if (IdentityServerDateTime.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { _logger.LogInformation("Showing login: Requested MaxAge exceeded."); return(new InteractionResponse() { IsLogin = true }); } } // check local idp restrictions if (currentIdp == IdentityServerConstants.LocalIdentityProvider && !request.Client.EnableLocalLogin) { _logger.LogInformation("Showing login: User logged in locally, but client does not allow local logins"); return(new InteractionResponse() { IsLogin = true }); } // check external idp restrictions if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any()) { if (!request.Client.IdentityProviderRestrictions.Contains(currentIdp)) { _logger.LogInformation("Showing login: User is logged in with idp: {idp}, but idp not in client restriction list.", currentIdp); return(new InteractionResponse() { IsLogin = true }); } } return(new InteractionResponse()); }
public async Task IsActiveAsync(IsActiveContext context) { await Task.Run(() => context.IsActive = true); }
/// <summary> /// Processes the login logic. /// </summary> /// <param name="request">The request.</param> /// <returns></returns> protected internal virtual async Task <InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request) { if (request.PromptModes.Contains(OidcConstants.PromptModes.Login) || request.PromptModes.Contains(OidcConstants.PromptModes.SelectAccount)) { Logger.LogInformation("Showing login: request contains prompt={0}", request.PromptModes.ToSpaceSeparatedString()); // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.RemovePrompt(); return(new InteractionResponse { IsLogin = true }); } // unauthenticated user var isAuthenticated = request.Subject.IsAuthenticated(); // user de-activated bool isActive = false; if (isAuthenticated) { var isActiveCtx = new IsActiveContext(request.Subject, request.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizeEndpoint); await Profile.IsActiveAsync(isActiveCtx); isActive = isActiveCtx.IsActive; } if (!isAuthenticated || !isActive) { if (!isAuthenticated) { Logger.LogInformation("Showing login: User is not authenticated"); } else if (!isActive) { Logger.LogInformation("Showing login: User is not active"); } return(new InteractionResponse { IsLogin = true }); } // check current idp var currentIdp = request.Subject.GetIdentityProvider(); // check if idp login hint matches current provider var idp = request.GetIdP(); if (idp.IsPresent()) { if (idp != currentIdp) { Logger.LogInformation("Showing login: Current IdP ({currentIdp}) is not the requested IdP ({idp})", currentIdp, idp); return(new InteractionResponse { IsLogin = true }); } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = request.Subject.GetAuthenticationTime(); if (Clock.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { Logger.LogInformation("Showing login: Requested MaxAge exceeded."); return(new InteractionResponse { IsLogin = true }); } } // check local idp restrictions if (currentIdp == IdentityServerConstants.LocalIdentityProvider) { if (!request.Client.EnableLocalLogin) { Logger.LogInformation("Showing login: User logged in locally, but client does not allow local logins"); return(new InteractionResponse { IsLogin = true }); } } // check external idp restrictions if user not using local idp else if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any() && !request.Client.IdentityProviderRestrictions.Contains(currentIdp)) { Logger.LogInformation("Showing login: User is logged in with idp: {idp}, but idp not in client restriction list.", currentIdp); return(new InteractionResponse { IsLogin = true }); } // check client's user SSO timeout if (request.Client.UserSsoLifetime.HasValue) { var authTimeEpoch = request.Subject.GetAuthenticationTimeEpoch(); var nowEpoch = Clock.UtcNow.ToUnixTimeSeconds(); var diff = nowEpoch - authTimeEpoch; if (diff > request.Client.UserSsoLifetime.Value) { Logger.LogInformation("Showing login: User's auth session duration: {sessionDuration} exceeds client's user SSO lifetime: {userSsoLifetime}.", diff, request.Client.UserSsoLifetime); return(new InteractionResponse { IsLogin = true }); } } return(new InteractionResponse()); }
public async Task IsActiveAsync(IsActiveContext context) { }
/// <summary> /// Validates a refresh token /// </summary> /// <param name="tokenHandle">The token handle.</param> /// <param name="client">The client.</param> /// <returns></returns> public virtual async Task <TokenValidationResult> ValidateRefreshTokenAsync(string tokenHandle, Client client) { var invalidGrant = new TokenValidationResult { IsError = true, Error = OidcConstants.TokenErrors.InvalidGrant }; Logger.LogTrace("Start refresh token validation"); ///////////////////////////////////////////// // check if refresh token is valid ///////////////////////////////////////////// var refreshToken = await RefreshTokenStore.GetRefreshTokenAsync(tokenHandle); if (refreshToken == null) { Logger.LogWarning("Invalid refresh token"); return(invalidGrant); } ///////////////////////////////////////////// // check if refresh token has expired ///////////////////////////////////////////// if (refreshToken.CreationTime.HasExceeded(refreshToken.Lifetime, Clock.UtcNow.DateTime)) { Logger.LogWarning("Refresh token has expired."); return(invalidGrant); } ///////////////////////////////////////////// // check if client belongs to requested refresh token ///////////////////////////////////////////// if (client.ClientId != refreshToken.ClientId) { Logger.LogError("{0} tries to refresh token belonging to {1}", client.ClientId, refreshToken.ClientId); return(invalidGrant); } ///////////////////////////////////////////// // check if client still has offline_access scope ///////////////////////////////////////////// if (!client.AllowOfflineAccess) { Logger.LogError("{clientId} does not have access to offline_access scope anymore", client.ClientId); return(invalidGrant); } ///////////////////////////////////////////// // check if refresh token has been consumed ///////////////////////////////////////////// if (refreshToken.ConsumedTime.HasValue) { if ((await AcceptConsumedTokenAsync(refreshToken)) == false) { Logger.LogWarning("Rejecting refresh token because it has been consumed already."); return(invalidGrant); } } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext( refreshToken.Subject, client, IdentityServerConstants.ProfileIsActiveCallers.RefreshTokenValidation); await Profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { Logger.LogError("{subjectId} has been disabled", refreshToken.Subject.GetSubjectId()); return(invalidGrant); } return(new TokenValidationResult { IsError = false, RefreshToken = refreshToken, Client = client }); }
public async Task IsActiveAsync(IsActiveContext context) { var user = await UserStore.FindBySubjectIdAsync(context.Subject.GetSubjectId()); context.IsActive = user != null; }
public Task IsActiveAsync(IsActiveContext context) { // here we should check if the user is active context.IsActive = true; return(Task.FromResult(0)); }
private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters) { Logger.Info("Start validation of authorization code token request"); ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (_validatedRequest.Client.Flow != Flows.AuthorizationCode && _validatedRequest.Client.Flow != Flows.Hybrid) { LogError("Client not authorized for code flow"); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate authorization code ///////////////////////////////////////////// var code = parameters.Get(Constants.TokenRequest.Code); if (code.IsMissing()) { var error = "Authorization code is missing."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCodeHandle = code; var authZcode = await _authorizationCodes.GetAsync(code); if (authZcode == null) { LogError("Invalid authorization code: " + code); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid handle"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } await _authorizationCodes.RemoveAsync(code); ///////////////////////////////////////////// // validate client binding ///////////////////////////////////////////// if (authZcode.Client.ClientId != _validatedRequest.Client.ClientId) { LogError(string.Format("Client {0} is trying to use a code from client {1}", _validatedRequest.Client.ClientId, authZcode.Client.ClientId)); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid client binding"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // validate code expiration ///////////////////////////////////////////// if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime)) { var error = "Authorization code is expired"; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCode = authZcode; ///////////////////////////////////////////// // validate redirect_uri ///////////////////////////////////////////// var redirectUri = parameters.Get(Constants.TokenRequest.RedirectUri); if (redirectUri.IsMissing()) { var error = "Redirect URI is missing."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false) { var error = "Invalid redirect_uri: " + redirectUri; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate scopes are present ///////////////////////////////////////////// if (_validatedRequest.AuthorizationCode.RequestedScopes == null || !_validatedRequest.AuthorizationCode.RequestedScopes.Any()) { var error = "Authorization code has no associated scopes."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client); await _users.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { var error = "User has been disabled: " + _validatedRequest.AuthorizationCode.Subject; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } Logger.Info("Validation of authorization code token request success"); await RaiseSuccessfulAuthorizationCodeRedeemedEventAsync(); return(Valid()); }
public async Task IsActiveAsync(IsActiveContext context) { CustomIdentityUser user = await _userManager.GetUserAsync(context.Subject); context.IsActive = (user != null) && user.IsActive; }
public Task IsActiveAsync(IsActiveContext context) { return(Task.FromResult(0)); }
/// <summary> /// Determines if the user is active. /// </summary> /// <param name="context"></param> /// <param name="user"></param> /// <returns></returns> protected virtual async Task IsActiveAsync(IsActiveContext context, ApplicationUser user) { context.IsActive = await IsUserActiveAsync(user); }
public Task IsActiveAsync(IsActiveContext context) { return(Task.CompletedTask); }
public Task IsActiveAsync(IsActiveContext context) { context.IsActive = true; return(Task.CompletedTask); }
public async Task IsActiveAsync(IsActiveContext context) { var sub = context.Subject.GetSubjectId(); var user = await _userManager.FindByIdAsync(sub); context.IsActive = user != null; }
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 _refreshTokenStore.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 _refreshTokenStore.RemoveRefreshTokenAsync(refreshTokenHandle); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // check if client belongs to requested refresh token ///////////////////////////////////////////// if (_validatedRequest.Client.ClientId != refreshToken.ClientId) { LogError("{0} tries to refresh token belonging to {1}", _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.AllowOfflineAccess) { 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()); }