private async Task <TokenRequestValidationResult> RunValidationAsync(Func <NameValueCollection, Task <TokenRequestValidationResult> > validationFunc, NameValueCollection parameters)
    {
        // run standard validation
        var result = await validationFunc(parameters);

        if (result.IsError)
        {
            return(result);
        }

        // run custom validation
        _logger.LogTrace("Calling into custom request validator: {type}", _customRequestValidator.GetType().FullName);

        var customValidationContext = new CustomTokenRequestValidationContext {
            Result = result
        };
        await _customRequestValidator.ValidateAsync(customValidationContext);

        if (customValidationContext.Result.IsError)
        {
            if (customValidationContext.Result.Error.IsPresent())
            {
                LogError("Custom token request validator", new { error = customValidationContext.Result.Error });
            }
            else
            {
                LogError("Custom token request validator error");
            }

            return(customValidationContext.Result);
        }

        LogSuccess();

        LicenseValidator.ValidateClient(customValidationContext.Result.ValidatedRequest.ClientId);

        return(customValidationContext.Result);
    }
    public async Task <AuthorizeRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject = null)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("AuthorizeRequestValidator.Validate");

        _logger.LogDebug("Start authorize request protocol validation");

        var request = new ValidatedAuthorizeRequest
        {
            Options    = _options,
            IssuerName = await _issuerNameService.GetCurrentAsync(),
            Subject    = subject ?? Principal.Anonymous,
            Raw        = parameters ?? throw new ArgumentNullException(nameof(parameters))
        };

        // load client_id
        // client_id must always be present on the request
        var loadClientResult = await LoadClientAsync(request);

        if (loadClientResult.IsError)
        {
            return(loadClientResult);
        }

        // load request object
        var roLoadResult = await LoadRequestObjectAsync(request);

        if (roLoadResult.IsError)
        {
            return(roLoadResult);
        }

        // validate request object
        var roValidationResult = await ValidateRequestObjectAsync(request);

        if (roValidationResult.IsError)
        {
            return(roValidationResult);
        }

        // validate client_id and redirect_uri
        var clientResult = await ValidateClientAsync(request);

        if (clientResult.IsError)
        {
            return(clientResult);
        }

        // state, response_type, response_mode
        var mandatoryResult = ValidateCoreParameters(request);

        if (mandatoryResult.IsError)
        {
            return(mandatoryResult);
        }

        // scope, scope restrictions and plausability, and resource indicators
        var scopeResult = await ValidateScopeAndResourceAsync(request);

        if (scopeResult.IsError)
        {
            return(scopeResult);
        }

        // nonce, prompt, acr_values, login_hint etc.
        var optionalResult = await ValidateOptionalParametersAsync(request);

        if (optionalResult.IsError)
        {
            return(optionalResult);
        }

        // custom validator
        _logger.LogDebug("Calling into custom validator: {type}", _customValidator.GetType().FullName);
        var context = new CustomAuthorizeRequestValidationContext
        {
            Result = new AuthorizeRequestValidationResult(request)
        };
        await _customValidator.ValidateAsync(context);

        var customResult = context.Result;

        if (customResult.IsError)
        {
            LogError("Error in custom validation", customResult.Error, request);
            return(Invalid(request, customResult.Error, customResult.ErrorDescription));
        }

        _logger.LogTrace("Authorize request protocol validation successful");

        LicenseValidator.ValidateClient(request.ClientId);

        return(Valid(request));
    }