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("{clientId} does not have the custom grant type in the allowed list, therefore requested grant is not allowed", _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: {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: {error}", result.Error);
                    return(Invalid(result.Error, result.ErrorDescription, result.CustomResponse));
                }
                LogError("Invalid extension grant");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant, customResponse: result.CustomResponse));
            }

            if (result.Subject != null)
            {
                _validatedRequest.Subject = result.Subject;
            }

            _logger.LogDebug("Validation of extension grant token request success");
            return(Valid(result.CustomResponse));
        }
        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));
        }