private async Task <ValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters) { ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (_validatedRequest.Client.Flow != Flows.Code) { _logger.Error("Client not authorized for code flow"); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate authorization code ///////////////////////////////////////////// var code = parameters.Get(Constants.TokenRequest.Code); if (code.IsMissing()) { _logger.Error("Authorization code is missing."); return(Invalid(Constants.TokenErrors.InvalidGrant)); } var authZcode = await _authorizationCodes.GetAsync(code); if (authZcode == null) { _logger.ErrorFormat("Invalid authorization code: ", code); return(Invalid(Constants.TokenErrors.InvalidGrant)); } else { _logger.InformationFormat("Authorization code found: {0}", code); } await _authorizationCodes.RemoveAsync(code); ///////////////////////////////////////////// // validate client binding ///////////////////////////////////////////// if (authZcode.Client.ClientId != _validatedRequest.Client.ClientId) { _logger.ErrorFormat("Client {0} is trying to use a code from client {1}", _validatedRequest.Client.ClientId, authZcode.Client.ClientId); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // validate code expiration ///////////////////////////////////////////// if (authZcode.CreationTime.HasExpired(_validatedRequest.Client.AuthorizationCodeLifetime)) { _logger.Error("Authorization code is expired"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCode = authZcode; ///////////////////////////////////////////// // validate redirect_uri ///////////////////////////////////////////// var redirectUri = parameters.Get(Constants.TokenRequest.RedirectUri); if (redirectUri.IsMissing()) { _logger.Error("Redirect URI is missing."); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } if (redirectUri != _validatedRequest.AuthorizationCode.RedirectUri.AbsoluteUri) { _logger.ErrorFormat("Invalid redirect_uri: {0}", redirectUri); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } return(Valid()); }
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.Code) && !_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()) { var error = "Authorization code is missing."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } if (code.Length > _options.InputLengthRestrictions.AuthorizationCode) { var error = "Authorization code is too long."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(null, error); return(Invalid(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCodeHandle = code; var authZcode = await _authorizationCodes.GetAsync(code); if (authZcode == null) { LogError("Authorization code cannot be found in the store: " + code); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, "Invalid handle"); return(Invalid(OidcConstants.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(OidcConstants.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(OidcConstants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCode = authZcode; ///////////////////////////////////////////// // validate redirect_uri ///////////////////////////////////////////// var redirectUri = parameters.Get(OidcConstants.TokenRequest.RedirectUri); if (redirectUri.IsMissing()) { var error = "Redirect URI is missing."; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(OidcConstants.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(OidcConstants.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(OidcConstants.TokenErrors.InvalidRequest)); } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { var error = "User has been disabled: " + _validatedRequest.AuthorizationCode.Subject; LogError(error); await RaiseFailedAuthorizationCodeRedeemedEventAsync(code, error); return(Invalid(OidcConstants.TokenErrors.InvalidRequest)); } _logger.LogInformation("Validation of authorization code token request success"); await RaiseSuccessfulAuthorizationCodeRedeemedEventAsync(); return(Valid()); }
private async Task <ValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters) { ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (_validatedRequest.Client.Flow != Flows.AuthorizationCode && _validatedRequest.Client.Flow != Flows.Hybrid) { Logger.Error("Client not authorized for code flow"); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate authorization code ///////////////////////////////////////////// var code = parameters.Get(Constants.TokenRequest.Code); if (code.IsMissing()) { Logger.Error("Authorization code is missing."); return(Invalid(Constants.TokenErrors.InvalidGrant)); } var authZcode = await _authorizationCodes.GetAsync(code); if (authZcode == null) { Logger.ErrorFormat("Invalid authorization code: {0}", code); return(Invalid(Constants.TokenErrors.InvalidGrant)); } Logger.InfoFormat("Authorization code found: {0}", code); await _authorizationCodes.RemoveAsync(code); ///////////////////////////////////////////// // validate client binding ///////////////////////////////////////////// if (authZcode.Client.ClientId != _validatedRequest.Client.ClientId) { Logger.ErrorFormat("Client {0} is trying to use a code from client {1}", _validatedRequest.Client.ClientId, authZcode.Client.ClientId); return(Invalid(Constants.TokenErrors.InvalidGrant)); } ///////////////////////////////////////////// // validate code expiration ///////////////////////////////////////////// if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime)) { Logger.Error("Authorization code is expired"); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCode = authZcode; ///////////////////////////////////////////// // validate redirect_uri ///////////////////////////////////////////// var redirectUri = parameters.Get(Constants.TokenRequest.RedirectUri); if (redirectUri.IsMissing()) { Logger.Error("Redirect URI is missing."); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } if (redirectUri != _validatedRequest.AuthorizationCode.RedirectUri.AbsoluteUri) { Logger.ErrorFormat("Invalid redirect_uri: {0}", redirectUri); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } ///////////////////////////////////////////// // validate scopes are present ///////////////////////////////////////////// if (_validatedRequest.AuthorizationCode.RequestedScopes == null || !_validatedRequest.AuthorizationCode.RequestedScopes.Any()) { Logger.Error("Authorization code has no associated scopes."); return(Invalid(Constants.TokenErrors.InvalidRequest)); } Logger.Info("Successful validation of authorization_code request"); return(Valid()); }
private async Task <ValidationResult> 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); RaiseFailedAuthorizationCodeRedeemedEvent(null, error); return(Invalid(Constants.TokenErrors.InvalidGrant)); } _validatedRequest.AuthorizationCodeHandle = code; var authZcode = await _authorizationCodes.GetAsync(code); if (authZcode == null) { LogError("Invalid authorization code: " + code); RaiseFailedAuthorizationCodeRedeemedEvent(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)); RaiseFailedAuthorizationCodeRedeemedEvent(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); RaiseFailedAuthorizationCodeRedeemedEvent(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); RaiseFailedAuthorizationCodeRedeemedEvent(code, error); return(Invalid(Constants.TokenErrors.UnauthorizedClient)); } if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false) { var error = "Invalid redirect_uri: " + redirectUri; LogError(error); RaiseFailedAuthorizationCodeRedeemedEvent(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); RaiseFailedAuthorizationCodeRedeemedEvent(code, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } ///////////////////////////////////////////// // make sure user is enabled ///////////////////////////////////////////// if (await _users.IsActiveAsync(_validatedRequest.AuthorizationCode.Subject) == false) { var error = "User has been disabled: " + _validatedRequest.AuthorizationCode.Subject; LogError(error); RaiseFailedAuthorizationCodeRedeemedEvent(code, error); return(Invalid(Constants.TokenErrors.InvalidRequest)); } Logger.Info("Validation of authorization code token request success"); RaiseSuccessfulAuthorizationCodeRedeemedEvent(); return(Valid()); }
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()); }