/// <summary> /// Initializes a new instance of the <see cref="TokenRequestValidationResult"/> class. /// </summary> /// <param name="validatedRequest">The validated request.</param> /// <param name="customResponse">The custom response.</param> public TokenRequestValidationResult(ValidatedTokenRequest validatedRequest, Dictionary <string, object> customResponse = null) { IsError = false; ValidatedRequest = validatedRequest; CustomResponse = customResponse; }
/// <summary> /// Validates the request. /// </summary> /// <param name="request">The request.</param> /// <returns></returns> public async Task <GrantValidationResult> ValidateAsync(ValidatedTokenRequest request) { var validator = _validators.FirstOrDefault(v => v.GrantType.Equals(request.GrantType, StringComparison.Ordinal)); if (validator == null) { _logger.LogError("No validator found for grant type"); return(new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType)); } try { _logger.LogTrace("Calling into custom grant validator: {type}", validator.GetType().FullName); var context = new ExtensionGrantValidationContext { Request = request }; await validator.ValidateAsync(context); return(context.Result); } catch (Exception e) { _logger.LogError(1, e, "Grant validation error: {message}", e.Message); return(new GrantValidationResult(TokenRequestErrors.InvalidGrant)); } }
/// <summary> /// Initializes a new instance of the <see cref="TokenRequestValidationResult"/> class. /// </summary> /// <param name="validatedRequest">The validated request.</param> /// <param name="error">The error.</param> /// <param name="errorDescription">The error description.</param> /// <param name="customResponse">The custom response.</param> public TokenRequestValidationResult(ValidatedTokenRequest validatedRequest, string error, string errorDescription = null, Dictionary <string, object> customResponse = null) { IsError = true; Error = error; ErrorDescription = errorDescription; ValidatedRequest = validatedRequest; CustomResponse = customResponse; }
/// <summary> /// Validates the request. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="clientValidationResult">The client validation result.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"> /// parameters /// or /// client /// </exception> public async Task <TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult) { _logger.LogDebug("Start token request validation"); _validatedRequest = new ValidatedTokenRequest { IssuerName = await _issuerNameService.GetCurrentAsync(), Raw = parameters ?? throw new ArgumentNullException(nameof(parameters)), Options = _options }; if (clientValidationResult == null) { throw new ArgumentNullException(nameof(clientValidationResult)); } _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret, clientValidationResult.Confirmation); ///////////////////////////////////////////// // check client protocol type ///////////////////////////////////////////// if (_validatedRequest.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect) { LogError("Invalid protocol type for client", new { clientId = _validatedRequest.Client.ClientId, expectedProtocolType = IdentityServerConstants.ProtocolTypes.OpenIdConnect, actualProtocolType = _validatedRequest.Client.ProtocolType }); return(Invalid(OidcConstants.TokenErrors.InvalidClient)); } ///////////////////////////////////////////// // check grant type ///////////////////////////////////////////// var grantType = parameters.Get(OidcConstants.TokenRequest.GrantType); if (grantType.IsMissing()) { LogError("Grant type is missing"); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType)); } if (grantType.Length > _options.InputLengthRestrictions.GrantType) { LogError("Grant type is too long"); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType)); } _validatedRequest.GrantType = grantType; ////////////////////////////////////////////////////////// // check for resource indicator and basic formatting ////////////////////////////////////////////////////////// var resourceIndicators = parameters.GetValues(OidcConstants.TokenRequest.Resource) ?? Enumerable.Empty <string>(); if (resourceIndicators?.Any(x => x.Length > _options.InputLengthRestrictions.ResourceIndicatorMaxLength) == true) { return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Resource indicator maximum length exceeded")); } if (!resourceIndicators.AreValidResourceIndicatorFormat(_logger)) { return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Invalid resource indicator format")); } if (resourceIndicators.Count() > 1) { return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Multiple resource indicators not supported on token endpoint.")); } _validatedRequest.RequestedResourceIndicator = resourceIndicators.SingleOrDefault(); ////////////////////////////////////////////////////////// // run specific logic for grants ////////////////////////////////////////////////////////// switch (grantType) { case OidcConstants.GrantTypes.AuthorizationCode: return(await RunValidationAsync(ValidateAuthorizationCodeRequestAsync, parameters)); case OidcConstants.GrantTypes.ClientCredentials: return(await RunValidationAsync(ValidateClientCredentialsRequestAsync, parameters)); case OidcConstants.GrantTypes.Password: return(await RunValidationAsync(ValidateResourceOwnerCredentialRequestAsync, parameters)); case OidcConstants.GrantTypes.RefreshToken: return(await RunValidationAsync(ValidateRefreshTokenRequestAsync, parameters)); case OidcConstants.GrantTypes.DeviceCode: return(await RunValidationAsync(ValidateDeviceCodeRequestAsync, parameters)); default: return(await RunValidationAsync(ValidateExtensionGrantRequestAsync, parameters)); } }
/// <summary> /// Validates the request. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="clientValidationResult">The client validation result.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"> /// parameters /// or /// client /// </exception> public async Task <TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult) { _logger.LogDebug("Start token request validation"); _validatedRequest = new ValidatedTokenRequest { Raw = parameters ?? throw new ArgumentNullException(nameof(parameters)), Options = _options }; if (clientValidationResult == null) { throw new ArgumentNullException(nameof(clientValidationResult)); } _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret, clientValidationResult.Confirmation); ///////////////////////////////////////////// // check client protocol type ///////////////////////////////////////////// if (_validatedRequest.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect) { LogError("Invalid protocol type for client", new { clientId = _validatedRequest.Client.ClientId, expectedProtocolType = IdentityServerConstants.ProtocolTypes.OpenIdConnect, actualProtocolType = _validatedRequest.Client.ProtocolType }); return(Invalid(OidcConstants.TokenErrors.InvalidClient)); } ///////////////////////////////////////////// // check grant type ///////////////////////////////////////////// var grantType = parameters.Get(OidcConstants.TokenRequest.GrantType); if (grantType.IsMissing()) { LogError("Grant type is missing"); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType)); } if (grantType.Length > _options.InputLengthRestrictions.GrantType) { LogError("Grant type is too long"); return(Invalid(OidcConstants.TokenErrors.UnsupportedGrantType)); } _validatedRequest.GrantType = grantType; switch (grantType) { case OidcConstants.GrantTypes.AuthorizationCode: return(await RunValidationAsync(ValidateAuthorizationCodeRequestAsync, parameters)); case OidcConstants.GrantTypes.ClientCredentials: return(await RunValidationAsync(ValidateClientCredentialsRequestAsync, parameters)); case OidcConstants.GrantTypes.Password: return(await RunValidationAsync(ValidateResourceOwnerCredentialRequestAsync, parameters)); case OidcConstants.GrantTypes.RefreshToken: return(await RunValidationAsync(ValidateRefreshTokenRequestAsync, parameters)); case OidcConstants.GrantTypes.DeviceCode: return(await RunValidationAsync(ValidateDeviceCodeRequestAsync, parameters)); default: return(await RunValidationAsync(ValidateExtensionGrantRequestAsync, parameters)); } }