protected virtual async Task Check(HandlerContext context)
        {
            var jObj       = context.Request.Data;
            var grantTypes = GetDefaultGrantTypes(jObj);
            var scopes     = GetDefaultScopes(jObj);
            var tokenEndpointAuthMethod = GetDefaultTokenAuthMethod(jObj);
            var responseTypes           = GetDefaultResponseTypes(jObj);
            var redirectUris            = jObj.GetRedirectUrisFromRegisterRequest();
            var clientNames             = jObj.GetClientNamesFromRegisterRequest();
            var clientUris                = jObj.GetClientUrisFromRegisterRequest();
            var logoUris                  = jObj.GetLogoUrisFromRegisterRequest();
            var contacts                  = jObj.GetContactsFromRegisterRequest();
            var tosUris                   = jObj.GetTosUrisFromRegisterRequest();
            var policyUris                = jObj.GetPolicyUrisFromRegisterRequest();
            var jwksUri                   = jObj.GetJwksUriFromRegisterRequest();
            var jwks                      = jObj.GetJwksFromRegisterRequest();
            var softwareStatement         = jObj.GetSoftwareStatementFromRegisterRequest();
            var softwareId                = jObj.GetSoftwareIdFromRegisterRequest();
            var softwareVersion           = jObj.GetSoftwareVersionFromRegisterRequest();
            var authGrantTypes            = _responseTypeHandlers.Select(r => r.GrantType);
            var supportedGrantTypes       = _grantTypeHandlers.Select(g => g.GrantType).Union(authGrantTypes).Distinct();
            var notSupportedGrantTypes    = grantTypes.Where(gt => !supportedGrantTypes.Any(sgt => sgt == gt));
            var tokenSignedResponseAlg    = jObj.GetTokenSignedResponseAlgFromRegisterRequest();
            var tokenEncryptedResponseAlg = jObj.GetTokenEncryptedResponseAlgFromRegisterRequest();
            var tokenEncryptedResponseEnc = jObj.GetTokenEncryptedResponseEncFromRegisterRequest();

            if (notSupportedGrantTypes.Any())
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.UNSUPPORTED_GRANT_TYPES, string.Join(",", notSupportedGrantTypes)));
            }

            if (!string.IsNullOrWhiteSpace(tokenEndpointAuthMethod) && !_oauthClientAuthenticationHandlers.Any(o => o.AuthMethod == tokenEndpointAuthMethod))
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.UNKNOWN_AUTH_METHOD, tokenEndpointAuthMethod));
            }

            var supportedResponseTypeHandlers = _responseTypeHandlers.Where(r => grantTypes.Contains(r.GrantType));

            if (supportedResponseTypeHandlers.Any())
            {
                var supportedResponseTypes   = supportedResponseTypeHandlers.Select(s => s.ResponseType);
                var unSupportedResponseTypes = responseTypes.Where(r => !supportedResponseTypes.Contains(r));
                if (unSupportedResponseTypes.Any())
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.BAD_RESPONSE_TYPES, string.Join(",", unSupportedResponseTypes)));
                }
            }

            foreach (var kvp in supportedResponseTypeHandlers.GroupBy(k => k.GrantType))
            {
                if (!kvp.Any(k => responseTypes.Contains(k.ResponseType)))
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.MISSING_RESPONSE_TYPE, kvp.Key));
                }
            }

            if (supportedResponseTypeHandlers.Any())
            {
                if (redirectUris == null || !redirectUris.Any())
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.MISSING_PARAMETER, RegisterRequestParameters.RedirectUris));
                }

                foreach (var redirectUrl in redirectUris)
                {
                    CheckRedirectUrl(context, redirectUrl);
                }
            }

            var existingScopeNames = (await _oauthScopeRepository.FindOAuthScopesByNames(scopes)).Select(s => s.Name);
            var unsupportedScopes  = scopes.Except(existingScopeNames);

            if (unsupportedScopes.Any())
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.UNSUPPORTED_SCOPES, string.Join(",", unsupportedScopes)));
            }

            CheckUri(jwksUri, ErrorMessages.BAD_JWKS_URI);
            CheckUris(clientUris, ErrorMessages.BAD_CLIENT_URI);
            CheckUris(logoUris, ErrorMessages.BAD_LOGO_URI);
            CheckUris(tosUris, ErrorMessages.BAD_TOS_URI);
            CheckUris(policyUris, ErrorMessages.BAD_POLICY_URI);
            CheckSignature(tokenSignedResponseAlg, ErrorMessages.UNSUPPORTED_TOKEN_SIGNED_RESPONSE_ALG);
            CheckEncryption(tokenEncryptedResponseAlg, tokenEncryptedResponseEnc, ErrorMessages.UNSUPPORTED_TOKEN_ENCRYPTED_RESPONSE_ALG, ErrorMessages.UNSUPPORTED_TOKEN_ENCRYPTED_RESPONSE_ENC, RegisterRequestParameters.TokenEncryptedResponseAlg);
            if (!string.IsNullOrWhiteSpace(jwksUri) && jwks != null)
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, ErrorMessages.DUPLICATE_JWKS);
            }
        }
        private async Task <IActionResult> Common(JObject content, CancellationToken cancellationToken)
        {
            try
            {
                var accessToken = ExtractAccessToken(content);
                var jwsPayload  = await Extract(accessToken);

                if (jwsPayload == null)
                {
                    throw new OAuthException(ErrorCodes.INVALID_TOKEN, OAuth.ErrorMessages.BAD_TOKEN);
                }

                var subject   = jwsPayload.GetSub();
                var scopes    = jwsPayload.GetScopes();
                var audiences = jwsPayload.GetAudiences();
                var claims    = jwsPayload.GetClaimsFromAccessToken(AuthorizationRequestClaimTypes.UserInfo);
                var authTime  = jwsPayload.GetAuthTime();
                var user      = await _oauthUserRepository.FindOAuthUserByLogin(subject, cancellationToken);

                if (user == null)
                {
                    return(new UnauthorizedResult());
                }

                var filteredClients = await _oauthClientRepository.FindOAuthClientByIds(audiences, cancellationToken);

                if (!filteredClients.Any())
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT, ErrorMessages.INVALID_AUDIENCE);
                }

                var oauthClient = (OpenIdClient)filteredClients.First();
                if (!user.HasOpenIDConsent(oauthClient.ClientId, scopes, claims, AuthorizationRequestClaimTypes.UserInfo))
                {
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.NO_CONSENT);
                }

                var token = await _tokenQueryRepository.Get(accessToken, cancellationToken);

                if (token == null)
                {
                    _logger.LogError("Cannot get user information because access token has been rejected");
                    throw new OAuthException(ErrorCodes.INVALID_TOKEN, OAuth.ErrorMessages.ACCESS_TOKEN_REJECTED);
                }

                var oauthScopes = (await _oauthScopeRepository.FindOAuthScopesByNames(scopes, cancellationToken)).Cast <OpenIdScope>();
                var payload     = new JwsPayload();
                IdTokenBuilder.EnrichWithScopeParameter(payload, oauthScopes, user, subject);
                _claimsJwsPayloadEnricher.EnrichWithClaimsParameter(payload, claims, user, authTime, AuthorizationRequestClaimTypes.UserInfo);
                foreach (var claimsSource in _claimsSources)
                {
                    await claimsSource.Enrich(payload, oauthClient).ConfigureAwait(false);
                }

                string contentType = "application/json";
                var    result      = JsonConvert.SerializeObject(payload).ToString();
                if (!string.IsNullOrWhiteSpace(oauthClient.UserInfoSignedResponseAlg))
                {
                    result = await _jwtBuilder.BuildClientToken(oauthClient, payload, oauthClient.UserInfoSignedResponseAlg, oauthClient.UserInfoEncryptedResponseAlg, oauthClient.UserInfoEncryptedResponseEnc);

                    contentType = "application/jwt";
                }

                return(new ContentResult
                {
                    Content = result,
                    ContentType = contentType
                });
            }
            catch (OAuthException ex)
            {
                var jObj = new JObject
                {
                    { ErrorResponseParameters.Error, ex.Code },
                    { ErrorResponseParameters.ErrorDescription, ex.Message }
                };
                return(new ContentResult
                {
                    Content = jObj.ToString(),
                    ContentType = "application/json",
                    StatusCode = (int)HttpStatusCode.BadRequest
                });
            }
        }
        public virtual async Task Validate(OAuthClient client, CancellationToken cancellationToken)
        {
            var authGrantTypes         = _responseTypeHandlers.Select(r => r.GrantType);
            var supportedGrantTypes    = _grantTypeHandlers.Select(g => g.GrantType).Union(authGrantTypes).Distinct();
            var notSupportedGrantTypes = client.GrantTypes.Where(gt => !supportedGrantTypes.Any(sgt => sgt == gt));

            if (notSupportedGrantTypes.Any())
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.UNSUPPORTED_GRANT_TYPES, string.Join(",", notSupportedGrantTypes)));
            }

            if (!string.IsNullOrWhiteSpace(client.TokenEndPointAuthMethod) && !_oauthClientAuthenticationHandlers.Any(o => o.AuthMethod == client.TokenEndPointAuthMethod))
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.UNKNOWN_AUTH_METHOD, client.TokenEndPointAuthMethod));
            }

            var supportedResponseTypeHandlers = _responseTypeHandlers.Where(r => client.GrantTypes.Contains(r.GrantType));

            if (supportedResponseTypeHandlers.Any())
            {
                var supportedResponseTypes   = supportedResponseTypeHandlers.Select(s => s.ResponseType);
                var unSupportedResponseTypes = client.ResponseTypes.Where(r => !supportedResponseTypes.Contains(r));
                if (unSupportedResponseTypes.Any())
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.BAD_RESPONSE_TYPES, string.Join(",", unSupportedResponseTypes)));
                }
            }

            foreach (var kvp in supportedResponseTypeHandlers.GroupBy(k => k.GrantType))
            {
                if (!kvp.Any(k => client.ResponseTypes.Contains(k.ResponseType)))
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.MISSING_RESPONSE_TYPE, kvp.Key));
                }
            }

            if (supportedResponseTypeHandlers.Any())
            {
                if (client.RedirectionUrls == null || !client.RedirectionUrls.Any())
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.MISSING_PARAMETER, OAuthClientParameters.RedirectUris));
                }

                foreach (var redirectUrl in client.RedirectionUrls)
                {
                    CheckRedirectUrl(client, redirectUrl);
                }
            }

            var scopes             = client.AllowedScopes.Select(_ => _.Name);
            var existingScopeNames = (await _oauthScopeRepository.FindOAuthScopesByNames(scopes, cancellationToken)).Select(s => s.Name);
            var unsupportedScopes  = scopes.Except(existingScopeNames);

            if (unsupportedScopes.Any())
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, string.Format(ErrorMessages.UNSUPPORTED_SCOPES, string.Join(",", unsupportedScopes)));
            }

            CheckUri(client.JwksUri, ErrorMessages.BAD_JWKS_URI);
            CheckUris(client.ClientUris, ErrorMessages.BAD_CLIENT_URI);
            CheckUris(client.LogoUris, ErrorMessages.BAD_LOGO_URI);
            CheckUris(client.TosUris, ErrorMessages.BAD_TOS_URI);
            CheckUris(client.PolicyUris, ErrorMessages.BAD_POLICY_URI);
            CheckSignature(client.TokenSignedResponseAlg, ErrorMessages.UNSUPPORTED_TOKEN_SIGNED_RESPONSE_ALG);
            CheckEncryption(client.TokenEncryptedResponseAlg, client.TokenEncryptedResponseEnc, ErrorMessages.UNSUPPORTED_TOKEN_ENCRYPTED_RESPONSE_ALG, ErrorMessages.UNSUPPORTED_TOKEN_ENCRYPTED_RESPONSE_ENC, OAuthClientParameters.TokenEncryptedResponseAlg);
            if (!string.IsNullOrWhiteSpace(client.JwksUri) && client.JsonWebKeys != null)
            {
                throw new OAuthException(ErrorCodes.INVALID_CLIENT_METADATA, ErrorMessages.DUPLICATE_JWKS);
            }
        }