コード例 #1
0
    public async Task StoreAuthorizationCodeAsync_should_persist_grant()
    {
        var code1 = new AuthorizationCode()
        {
            ClientId        = "test",
            CreationTime    = DateTime.UtcNow,
            Lifetime        = 10,
            Subject         = _user,
            CodeChallenge   = "challenge",
            RedirectUri     = "http://client/cb",
            Nonce           = "nonce",
            RequestedScopes = new string[] { "scope1", "scope2" }
        };

        var handle = await _codes.StoreAuthorizationCodeAsync(code1);

        var code2 = await _codes.GetAuthorizationCodeAsync(handle);

        code1.ClientId.Should().Be(code2.ClientId);
        code1.CreationTime.Should().Be(code2.CreationTime);
        code1.Lifetime.Should().Be(code2.Lifetime);
        code1.Subject.GetSubjectId().Should().Be(code2.Subject.GetSubjectId());
        code1.CodeChallenge.Should().Be(code2.CodeChallenge);
        code1.RedirectUri.Should().Be(code2.RedirectUri);
        code1.Nonce.Should().Be(code2.Nonce);
        code1.RequestedScopes.Should().BeEquivalentTo(code2.RequestedScopes);
    }
コード例 #2
0
        private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters)
        {
            _logger.LogDebug("Start validation of authorization code token request");

            /////////////////////////////////////////////
            // check if client is authorized for grant type
            /////////////////////////////////////////////
            if (!_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.AuthorizationCode) &&
                !_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.Hybrid))
            {
                LogError("Client not authorized for code flow");
                return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // validate authorization code
            /////////////////////////////////////////////
            var code = parameters.Get(OidcConstants.TokenRequest.Code);

            if (code.IsMissing())
            {
                LogError("Authorization code is missing");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            if (code.Length > _options.InputLengthRestrictions.AuthorizationCode)
            {
                LogError("Authorization code is too long");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCodeHandle = code;

            var authZcode = await _authorizationCodeStore.GetAuthorizationCodeAsync(code);

            if (authZcode == null)
            {
                LogError("Invalid authorization code: {code}", code);
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            await _authorizationCodeStore.RemoveAuthorizationCodeAsync(code);

            if (authZcode.CreationTime.HasExceeded(authZcode.Lifetime, _options.UtcNow))
            {
                LogError("Authorization code expired: {code}", code);
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // populate session id
            /////////////////////////////////////////////
            if (authZcode.SessionId.IsPresent())
            {
                _validatedRequest.SessionId = authZcode.SessionId;
            }

            /////////////////////////////////////////////
            // validate client binding
            /////////////////////////////////////////////
            if (authZcode.ClientId != _validatedRequest.Client.ClientId)
            {
                LogError("Client {0} is trying to use a code from client {1}", _validatedRequest.Client.ClientId, authZcode.ClientId);
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            /////////////////////////////////////////////
            // validate code expiration
            /////////////////////////////////////////////
            if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime, _options.UtcNow))
            {
                LogError("Authorization code is expired");
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _validatedRequest.AuthorizationCode = authZcode;

            /////////////////////////////////////////////
            // validate redirect_uri
            /////////////////////////////////////////////
            var redirectUri = parameters.Get(OidcConstants.TokenRequest.RedirectUri);

            if (redirectUri.IsMissing())
            {
                LogError("Redirect URI is missing");
                return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
            }

            if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false)
            {
                LogError("Invalid redirect_uri: {redirectUri}", redirectUri);
                return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
            }

            /////////////////////////////////////////////
            // validate scopes are present
            /////////////////////////////////////////////
            if (_validatedRequest.AuthorizationCode.RequestedScopes == null ||
                !_validatedRequest.AuthorizationCode.RequestedScopes.Any())
            {
                LogError("Authorization code has no associated scopes");
                return(Invalid(OidcConstants.TokenErrors.InvalidRequest));
            }

            /////////////////////////////////////////////
            // validate PKCE parameters
            /////////////////////////////////////////////
            var codeVerifier = parameters.Get(OidcConstants.TokenRequest.CodeVerifier);

            if (_validatedRequest.Client.RequirePkce || _validatedRequest.AuthorizationCode.CodeChallenge.IsPresent())
            {
                _logger.LogDebug("Client required a proof key for code exchange. Starting PKCE validation");

                var proofKeyResult = ValidateAuthorizationCodeWithProofKeyParameters(codeVerifier, _validatedRequest.AuthorizationCode);
                if (proofKeyResult.IsError)
                {
                    return(proofKeyResult);
                }

                _validatedRequest.CodeVerifier = codeVerifier;
            }
            else
            {
                if (codeVerifier.IsPresent())
                {
                    LogError("Unexpected code_verifier: {codeVerifier}. This happens when the client is trying to use PKCE, but it is not enabled. Set RequirePkce to true.", codeVerifier);
                    return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
                }
            }

            /////////////////////////////////////////////
            // make sure user is enabled
            /////////////////////////////////////////////
            var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizationCodeValidation);
            await _profile.IsActiveAsync(isActiveCtx);

            if (isActiveCtx.IsActive == false)
            {
                LogError("User has been disabled: {subjectId}", _validatedRequest.AuthorizationCode.Subject.GetSubjectId());
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }

            _logger.LogDebug("Validation of authorization code token request success");

            return(Valid());
        }
コード例 #3
0
        public async Task RemoveAllGrantsAsync_should_remove_all_grants()
        {
            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "123",
                Scopes    = new string[] { "foo1", "foo2" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client2",
                SubjectId = "123",
                Scopes    = new string[] { "foo3" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "456",
                Scopes    = new string[] { "foo3" }
            });

            await _referenceTokens.StoreReferenceTokenAsync("key1", new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar1"),
                    new Claim("scope", "bar2"),
                },
            });

            await _referenceTokens.StoreReferenceTokenAsync("key2", new Token()
            {
                ClientId     = "client2",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar3"),
                },
            });

            await _referenceTokens.StoreReferenceTokenAsync("key3", new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.Now,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "456"),
                    new Claim("scope", "bar3"),
                },
            });

            await _refreshTokens.StoreRefreshTokenAsync("key4", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz1"),
                        new Claim("scope", "baz2")
                    }
                },
                Version = 1
            });

            await _refreshTokens.StoreRefreshTokenAsync("key5", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "456"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            await _refreshTokens.StoreRefreshTokenAsync("key6", new RefreshToken()
            {
                CreationTime = DateTime.Now,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client2",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.Now,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz3"),
                    }
                },
                Version = 1
            });

            await _codes.StoreAuthorizationCodeAsync("key7", new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux1", "quux2" }
            });

            await _codes.StoreAuthorizationCodeAsync("key8", new AuthorizationCode()
            {
                ClientId        = "client2",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _codes.StoreAuthorizationCodeAsync("key9", new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.Now,
                Lifetime        = 10,
                Subject         = IdentityServerPrincipal.Create("456", "alice"),
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _subject.RemoveAllGrantsAsync("123", "client1");

            (await _referenceTokens.GetReferenceTokenAsync("key1")).Should().BeNull();
            (await _referenceTokens.GetReferenceTokenAsync("key2")).Should().NotBeNull();
            (await _referenceTokens.GetReferenceTokenAsync("key3")).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync("key4")).Should().BeNull();
            (await _refreshTokens.GetRefreshTokenAsync("key5")).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync("key6")).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync("key7")).Should().BeNull();
            (await _codes.GetAuthorizationCodeAsync("key8")).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync("key9")).Should().NotBeNull();
        }
コード例 #4
0
        public async Task RemoveAllGrantsAsync_should_remove_all_grants()
        {
            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "123",
                Scopes    = new string[] { "foo1", "foo2" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client2",
                SubjectId = "123",
                Scopes    = new string[] { "foo3" }
            });

            await _userConsent.StoreUserConsentAsync(new Consent()
            {
                ClientId  = "client1",
                SubjectId = "456",
                Scopes    = new string[] { "foo3" }
            });

            var handle1 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar1"),
                    new Claim("scope", "bar2")
                }
            });

            var handle2 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client2",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "123"),
                    new Claim("scope", "bar3")
                }
            });

            var handle3 = await _referenceTokens.StoreReferenceTokenAsync(new Token()
            {
                ClientId     = "client1",
                Audiences    = { "aud" },
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                Type         = "type",
                Claims       = new List <Claim>
                {
                    new Claim("sub", "456"),
                    new Claim("scope", "bar3")
                }
            });

            var handle4 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz1"),
                        new Claim("scope", "baz2")
                    }
                },
                Version = 1
            });

            var handle5 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client1",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "456"),
                        new Claim("scope", "baz3")
                    }
                },
                Version = 1
            });

            var handle6 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()
            {
                CreationTime = DateTime.UtcNow,
                Lifetime     = 10,
                AccessToken  = new Token
                {
                    ClientId     = "client2",
                    Audiences    = { "aud" },
                    CreationTime = DateTime.UtcNow,
                    Type         = "type",
                    Claims       = new List <Claim>
                    {
                        new Claim("sub", "123"),
                        new Claim("scope", "baz3")
                    }
                },
                Version = 1
            });

            var handle7 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux1", "quux2" }
            });

            var handle8 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client2",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = _user,
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            var handle9 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()
            {
                ClientId        = "client1",
                CreationTime    = DateTime.UtcNow,
                Lifetime        = 10,
                Subject         = new IdentityServerUser("456").CreatePrincipal(),
                CodeChallenge   = "challenge",
                RedirectUri     = "http://client/cb",
                Nonce           = "nonce",
                RequestedScopes = new string[] { "quux3" }
            });

            await _subject.RemoveAllGrantsAsync("123", "client1");

            (await _referenceTokens.GetReferenceTokenAsync(handle1)).Should().BeNull();
            (await _referenceTokens.GetReferenceTokenAsync(handle2)).Should().NotBeNull();
            (await _referenceTokens.GetReferenceTokenAsync(handle3)).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle4)).Should().BeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle5)).Should().NotBeNull();
            (await _refreshTokens.GetRefreshTokenAsync(handle6)).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync(handle7)).Should().BeNull();
            (await _codes.GetAuthorizationCodeAsync(handle8)).Should().NotBeNull();
            (await _codes.GetAuthorizationCodeAsync(handle9)).Should().NotBeNull();
        }
コード例 #5
0
    private async Task <TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters)
    {
        _logger.LogDebug("Start validation of authorization code token request");

        /////////////////////////////////////////////
        // check if client is authorized for grant type
        /////////////////////////////////////////////
        if (!_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.AuthorizationCode) &&
            !_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.Hybrid))
        {
            LogError("Client not authorized for code flow");
            return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
        }

        /////////////////////////////////////////////
        // validate authorization code
        /////////////////////////////////////////////
        var code = parameters.Get(OidcConstants.TokenRequest.Code);

        if (code.IsMissing())
        {
            LogError("Authorization code is missing");
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        if (code.Length > _options.InputLengthRestrictions.AuthorizationCode)
        {
            LogError("Authorization code is too long");
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        _validatedRequest.AuthorizationCodeHandle = code;

        var authZcode = await _authorizationCodeStore.GetAuthorizationCodeAsync(code);

        if (authZcode == null)
        {
            LogError("Invalid authorization code", new { code });
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        /////////////////////////////////////////////
        // validate client binding
        /////////////////////////////////////////////
        if (authZcode.ClientId != _validatedRequest.Client.ClientId)
        {
            LogError("Client is trying to use a code from a different client", new { clientId = _validatedRequest.Client.ClientId, codeClient = authZcode.ClientId });
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        // remove code from store
        // todo: set to consumed in the future?
        await _authorizationCodeStore.RemoveAuthorizationCodeAsync(code);

        if (authZcode.CreationTime.HasExceeded(authZcode.Lifetime, _clock.UtcNow.UtcDateTime))
        {
            LogError("Authorization code expired", new { code });
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        /////////////////////////////////////////////
        // populate session id
        /////////////////////////////////////////////
        if (authZcode.SessionId.IsPresent())
        {
            _validatedRequest.SessionId = authZcode.SessionId;
        }

        /////////////////////////////////////////////
        // validate code expiration
        /////////////////////////////////////////////
        if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime, _clock.UtcNow.UtcDateTime))
        {
            LogError("Authorization code is expired");
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        _validatedRequest.AuthorizationCode = authZcode;
        _validatedRequest.Subject           = authZcode.Subject;

        /////////////////////////////////////////////
        // validate redirect_uri
        /////////////////////////////////////////////
        var redirectUri = parameters.Get(OidcConstants.TokenRequest.RedirectUri);

        if (redirectUri.IsMissing())
        {
            LogError("Redirect URI is missing");
            return(Invalid(OidcConstants.TokenErrors.UnauthorizedClient));
        }

        if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false)
        {
            LogError("Invalid redirect_uri", new { redirectUri, expectedRedirectUri = _validatedRequest.AuthorizationCode.RedirectUri });
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        /////////////////////////////////////////////
        // validate scopes are present
        /////////////////////////////////////////////
        if (_validatedRequest.AuthorizationCode.RequestedScopes == null ||
            !_validatedRequest.AuthorizationCode.RequestedScopes.Any())
        {
            LogError("Authorization code has no associated scopes");
            return(Invalid(OidcConstants.TokenErrors.InvalidRequest));
        }

        //////////////////////////////////////////////////////////
        // resource indicator
        //////////////////////////////////////////////////////////
        if (_validatedRequest.RequestedResourceIndicator != null &&
            _validatedRequest.AuthorizationCode.RequestedResourceIndicators?.Any() == true &&
            !_validatedRequest.AuthorizationCode.RequestedResourceIndicators.Contains(_validatedRequest.RequestedResourceIndicator))
        {
            return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Resource indicator does not match any resource indicator in the original authorize request."));
        }

        //////////////////////////////////////////////////////////
        // resource and scope validation
        //////////////////////////////////////////////////////////
        var validatedResources = await _resourceValidator.ValidateRequestedResourcesAsync(new ResourceValidationRequest {
            Client             = _validatedRequest.Client,
            Scopes             = _validatedRequest.AuthorizationCode.RequestedScopes,
            ResourceIndicators = _validatedRequest.AuthorizationCode.RequestedResourceIndicators,
            // if we are issuing a refresh token, then we need to allow the non-isolated resource
            IncludeNonIsolatedApiResources = _validatedRequest.AuthorizationCode.RequestedScopes.Contains(OidcConstants.StandardScopes.OfflineAccess)
        });

        if (!validatedResources.Succeeded)
        {
            if (validatedResources.InvalidResourceIndicators.Any())
            {
                return(Invalid(OidcConstants.AuthorizeErrors.InvalidTarget, "Invalid resource indicator."));
            }
            if (validatedResources.InvalidScopes.Any())
            {
                return(Invalid(OidcConstants.AuthorizeErrors.InvalidScope, "Invalid scope."));
            }
        }

        LicenseValidator.ValidateResourceIndicators(_validatedRequest.RequestedResourceIndicator);
        _validatedRequest.ValidatedResources = validatedResources.FilterByResourceIndicator(_validatedRequest.RequestedResourceIndicator);

        /////////////////////////////////////////////
        // validate PKCE parameters
        /////////////////////////////////////////////
        var codeVerifier = parameters.Get(OidcConstants.TokenRequest.CodeVerifier);

        if (_validatedRequest.Client.RequirePkce || _validatedRequest.AuthorizationCode.CodeChallenge.IsPresent())
        {
            _logger.LogDebug("Client required a proof key for code exchange. Starting PKCE validation");

            var proofKeyResult = ValidateAuthorizationCodeWithProofKeyParameters(codeVerifier, _validatedRequest.AuthorizationCode);
            if (proofKeyResult.IsError)
            {
                return(proofKeyResult);
            }

            _validatedRequest.CodeVerifier = codeVerifier;
        }
        else
        {
            if (codeVerifier.IsPresent())
            {
                LogError("Unexpected code_verifier: {codeVerifier}. This happens when the client is trying to use PKCE, but it is not enabled. Set RequirePkce to true.", codeVerifier);
                return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
            }
        }

        /////////////////////////////////////////////
        // make sure user is enabled
        /////////////////////////////////////////////
        var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizationCodeValidation);
        await _profile.IsActiveAsync(isActiveCtx);

        if (isActiveCtx.IsActive == false)
        {
            LogError("User has been disabled", new { subjectId = _validatedRequest.AuthorizationCode.Subject.GetSubjectId() });
            return(Invalid(OidcConstants.TokenErrors.InvalidGrant));
        }

        _logger.LogDebug("Validation of authorization code token request success");

        return(Valid());
    }