/// <summary>
        /// Validates the current request.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public async Task <ClientSecretValidationResult> ValidateAsync(HttpContext context)
        {
            _logger.LogDebug("Start client validation");

            var fail = new ClientSecretValidationResult
            {
                IsError = true
            };

            var parsedSecret = await _parser.ParseAsync(context);

            if (parsedSecret == null)
            {
                await RaiseFailureEventAsync("unknown", "No client id found");

                _logger.LogError("No client identifier found");
                return(fail);
            }

            // load client
            var client = await _clients.FindEnabledClientByIdAsync(parsedSecret.Id);

            if (client == null)
            {
                await RaiseFailureEventAsync(parsedSecret.Id, "Unknown client");

                _logger.LogError("No client with id '{clientId}' found. aborting", parsedSecret.Id);
                return(fail);
            }

            SecretValidationResult secretValidationResult = null;

            if (!client.RequireClientSecret || client.IsImplicitOnly())
            {
                _logger.LogDebug("Public Client - skipping secret validation success");
            }
            else
            {
                secretValidationResult = await _validator.ValidateAsync(client.ClientSecrets, parsedSecret);

                if (secretValidationResult.Success == false)
                {
                    await RaiseFailureEventAsync(client.ClientId, "Invalid client secret");

                    _logger.LogError("Client secret validation failed for client: {clientId}.", client.ClientId);

                    return(fail);
                }
            }

            _logger.LogDebug("Client validation success");

            var success = new ClientSecretValidationResult
            {
                IsError      = false,
                Client       = client,
                Secret       = parsedSecret,
                Confirmation = secretValidationResult?.Confirmation
            };

            await RaiseSuccessEventAsync(client.ClientId, parsedSecret.Type);

            return(success);
        }
    /// <summary>
    /// Validates the secret on the current request.
    /// </summary>
    /// <param name="context">The context.</param>
    /// <returns></returns>
    public async Task <ApiSecretValidationResult> ValidateAsync(HttpContext context)
    {
        using var activity = Tracing.ValidationActivitySource.StartActivity("ApiSecretValidator.Validate");

        _logger.LogTrace("Start API validation");

        var fail = new ApiSecretValidationResult
        {
            IsError = true
        };

        var parsedSecret = await _parser.ParseAsync(context);

        if (parsedSecret == null)
        {
            await RaiseFailureEventAsync("unknown", "No API id or secret found");

            _logger.LogError("No API secret found");
            return(fail);
        }

        // load API resource
        var apis = await _resources.FindApiResourcesByNameAsync(new[] { parsedSecret.Id });

        if (apis == null || !apis.Any())
        {
            await RaiseFailureEventAsync(parsedSecret.Id, "Unknown API resource");

            _logger.LogError("No API resource with that name found. aborting");
            return(fail);
        }

        if (apis.Count() > 1)
        {
            await RaiseFailureEventAsync(parsedSecret.Id, "Invalid API resource");

            _logger.LogError("More than one API resource with that name found. aborting");
            return(fail);
        }

        var api = apis.Single();

        if (api.Enabled == false)
        {
            await RaiseFailureEventAsync(parsedSecret.Id, "API resource not enabled");

            _logger.LogError("API resource not enabled. aborting.");
            return(fail);
        }

        var result = await _validator.ValidateAsync(api.ApiSecrets, parsedSecret);

        if (result.Success)
        {
            _logger.LogDebug("API resource validation success");

            var success = new ApiSecretValidationResult
            {
                IsError  = false,
                Resource = api
            };

            await RaiseSuccessEventAsync(api.Name, parsedSecret.Type);

            return(success);
        }

        await RaiseFailureEventAsync(api.Name, "Invalid API secret");

        _logger.LogError("API validation failed.");

        return(fail);
    }
        /// <summary>
        /// Validates the current request.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public async Task <ClientSecretValidationResult> ValidateAsync(HttpContext context)
        {
            _logger.LogDebug("Start client validation");

            var fail = new ClientSecretValidationResult
            {
                IsError = true
            };

            var parsedSecret = await _parser.ParseAsync(context);

            if (parsedSecret == null)
            {
                await RaiseFailureEventAsync("unknown", "No client id found");

                _logger.LogError("No client identifier found");
                return(fail);
            }

            // load client
            var client = await _clients.FindEnabledClientByIdAsync(parsedSecret.Id) as ClientExtra;

            if (client == null)
            {
                await RaiseFailureEventAsync(parsedSecret.Id, $"Unknown client for tenant: '{_scopedTenantRequestContext.Context.TenantName}'");

                _logger.LogError($"No client with id '{parsedSecret.Id}' for tenant: '{_scopedTenantRequestContext.Context.TenantName}' found. aborting");
                return(fail);
            }


            SecretValidationResult secretValidationResult = null;

            if (!client.RequireClientSecret || client.IsImplicitOnly())
            {
                _logger.LogDebug("Public Client - skipping secret validation success");
            }
            else
            {
                ////////////////////////////////////////
                // Check if this is a refresh_token
                ////////////////////////////////////////
                bool continueValidation = true;
                if (!client.RequireRefreshClientSecret)
                {
                    try
                    {
                        var parameters = (await context.Request.ReadFormAsync()).AsNameValueCollection();
                        var grantType  = parameters.Get(OidcConstants.TokenRequest.GrantType);
                        if (!string.IsNullOrWhiteSpace(grantType) && grantType == OidcConstants.GrantTypes.RefreshToken)
                        {
                            // let it through
                            _logger.LogDebug("RequireRefreshClientSecret == false - skipping secret validation success");
                            continueValidation = false;
                        }
                    }
                    catch (Exception ex)
                    {
                        // let it through
                        _logger.LogDebug("RequireRefreshClientSecret == false - skipping secret validation success");
                        continueValidation = false;
                    }
                }
                if (continueValidation)
                {
                    secretValidationResult = await _validator.ValidateAsync(client.ClientSecrets, parsedSecret);

                    if (secretValidationResult.Success == false)
                    {
                        await RaiseFailureEventAsync(client.ClientId, "Invalid client secret");

                        _logger.LogError("Client secret validation failed for client: {clientId}.", client.ClientId);

                        return(fail);
                    }
                }
            }

            _logger.LogDebug("Client validation success");

            var success = new ClientSecretValidationResult
            {
                IsError      = false,
                Client       = client,
                Secret       = parsedSecret,
                Confirmation = secretValidationResult?.Confirmation
            };

            await RaiseSuccessEventAsync(client.ClientId, parsedSecret.Type);

            return(success);
        }