/// <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));
            }
        }
Example #2
0
        /// <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));
            }
        }