Exemple #1
0
        public async Task When_Requesting_Token_Via_AuthorizationCode_Grant_Type_Then_Events_Are_Logged()
        {
            // ARRANGE
            InitializeFakeObjects();
            const string clientId      = "clientId";
            const string code          = "code";
            const string accessToken   = "accessToken";
            const string identityToken = "identityToken";
            var          parameter     = new AuthorizationCodeGrantTypeParameter
            {
                ClientId = clientId,
                Code     = code
            };
            var grantedToken = new GrantedToken
            {
                AccessToken = accessToken,
                IdToken     = identityToken
            };

            _getTokenByAuthorizationCodeGrantTypeActionFake.Setup(
                g => g.Execute(It.IsAny <AuthorizationCodeGrantTypeParameter>(), It.IsAny <AuthenticationHeaderValue>()))
            .Returns(Task.FromResult(grantedToken));

            // ACT
            await _tokenActions.GetTokenByAuthorizationCodeGrantType(parameter, null);

            // ASSERTS
            _simpleIdentityServerEventSourceFake.Verify(s => s.StartGetTokenByAuthorizationCode(clientId, code));
            _simpleIdentityServerEventSourceFake.Verify(s => s.EndGetTokenByAuthorizationCode(accessToken, identityToken));
        }
        /// <summary>
        /// Check the parameters based on the RFC : http://openid.net/specs/openid-connect-core-1_0.html#TokenRequestValidation
        /// </summary>
        /// <param name="authorizationCodeGrantTypeParameter"></param>
        /// <param name="authenticationHeaderValue"></param>
        /// <param name="certificate"></param>
        /// <param name="issuerName"></param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the async operation.</param>
        /// <returns></returns>
        private async Task <Option <ValidationResult> > ValidateParameter(
            AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
            AuthenticationHeaderValue?authenticationHeaderValue,
            X509Certificate2?certificate,
            string issuerName,
            CancellationToken cancellationToken)
        {
            if (authorizationCodeGrantTypeParameter.Code == null)
            {
                return(new ErrorDetails
                {
                    Status = HttpStatusCode.BadRequest,
                    Title = ErrorCodes.InvalidGrant,
                    Detail = Strings.TheAuthorizationCodeIsNotCorrect
                });
            }

            // 1. Authenticate the client
            var instruction = authenticationHeaderValue.GetAuthenticateInstruction(
                authorizationCodeGrantTypeParameter,
                certificate);
            var authResult = await _authenticateClient.Authenticate(instruction, issuerName, cancellationToken)
                             .ConfigureAwait(false);

            var client = authResult.Client;

            if (client == null)
            {
                return(new ErrorDetails
                {
                    Status = HttpStatusCode.BadRequest,
                    Title = ErrorCodes.InvalidClient,
                    Detail = authResult.ErrorMessage !
                });
Exemple #3
0
        public async Task <GrantedToken> GetTokenByAuthorizationCodeGrantType(AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
                                                                              AuthenticationHeaderValue authenticationHeaderValue,
                                                                              X509Certificate2 certificate = null)
        {
            if (authorizationCodeGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationCodeGrantTypeParameter));
            }

            var processId = Guid.NewGuid().ToString();

            try
            {
                _eventPublisher.Publish(new GrantTokenViaAuthorizationCodeReceived(Guid.NewGuid().ToString(), processId, _payloadSerializer.GetPayload(authorizationCodeGrantTypeParameter, authenticationHeaderValue), authenticationHeaderValue, 0));
                _simpleIdentityServerEventSource.StartGetTokenByAuthorizationCode(
                    authorizationCodeGrantTypeParameter.ClientId,
                    authorizationCodeGrantTypeParameter.Code);
                _authorizationCodeGrantTypeParameterTokenEdpValidator.Validate(authorizationCodeGrantTypeParameter);
                var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, authenticationHeaderValue);

                _simpleIdentityServerEventSource.EndGetTokenByAuthorizationCode(
                    result.AccessToken,
                    result.IdToken);
                _eventPublisher.Publish(new TokenGranted(Guid.NewGuid().ToString(), processId, _payloadSerializer.GetPayload(result), 1));
                return(result);
            }
            catch (IdentityServerException ex)
            {
                _eventPublisher.Publish(new OpenIdErrorReceived(Guid.NewGuid().ToString(), processId, ex.Code, ex.Message, 1));
                throw;
            }
        }
        public async Task When_Requesting_An_Existed_Granted_Token_Then_Check_Id_Token_Is_Signed_And_Encrypted()
        {
            // ARRANGE
            InitializeFakeObjects();
            const string accessToken   = "accessToken";
            const string identityToken = "identityToken";
            const string clientId      = "clientId";
            var          authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = "clientSecret",
                RedirectUri         = "redirectUri",
                ClientId            = clientId
            };

            var result = new AuthenticationResult(new Models.Client {
                ClientId = "clientId",
                IdTokenSignedResponseAlg    = Jwt.Constants.JwsAlgNames.RS256,
                IdTokenEncryptedResponseAlg = Jwt.Constants.JweAlgNames.RSA1_5,
                IdTokenEncryptedResponseEnc = Jwt.Constants.JweEncNames.A128CBC_HS256
            }, null);
            var authorizationCode = new AuthorizationCode
            {
                ClientId       = clientId,
                RedirectUri    = "redirectUri",
                CreateDateTime = DateTime.UtcNow
            };
            var grantedToken = new GrantedToken
            {
                ClientId       = clientId,
                AccessToken    = accessToken,
                IdToken        = identityToken,
                IdTokenPayLoad = new JwsPayload()
            };

            _clientValidatorFake.Setup(c => c.CheckPkce(It.IsAny <Client>(), It.IsAny <string>(), It.IsAny <AuthorizationCode>()))
            .Returns(true);
            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>()))
            .Returns(Task.FromResult(result));
            _authorizationCodeRepositoryFake.Setup(a => a.GetAsync(It.IsAny <string>()))
            .Returns(Task.FromResult(authorizationCode));
            _simpleIdentityServerConfiguratorFake.Setup(s => s.GetAuthorizationCodeValidityPeriodInSecondsAsync())
            .Returns(Task.FromResult((double)3000));
            _clientValidatorFake.Setup(c => c.GetRedirectionUrls(It.IsAny <Models.Client>(), It.IsAny <string>()))
            .Returns(new[] { "redirectUri" });
            _grantedTokenHelperStub.Setup(g => g.GetValidGrantedTokenAsync(It.IsAny <string>(),
                                                                           It.IsAny <string>(),
                                                                           It.IsAny <JwsPayload>(),
                                                                           It.IsAny <JwsPayload>()))
            .Returns(Task.FromResult(grantedToken));

            // ACT
            await _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null);

            // ASSERTS
            _clientHelper.Verify(j => j.GenerateIdTokenAsync(It.IsAny <Client>(), It.IsAny <JwsPayload>()));
        }
        public async Task When_Client_Doesnt_Support_Grant_Type_Code_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId            = "clientId",
                ClientSecret        = "clientSecret"
            };

            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>(), null, It.IsAny <bool>()))
            .Returns(() => Task.FromResult(new AuthenticationResult(new Client
            {
                ClientId = "id"
            }, null)));

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync <IdentityServerException>(() =>
                                                                               _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null, null, null));

            Assert.True(exception.Code == ErrorCodes.InvalidClient);
            Assert.True(exception.Message == string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, "id", GrantType.authorization_code));
        }
        public async Task When_Redirect_Uri_Is_Not_The_Same_Then_Exception_Is_Thrown()
        {            
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId = "clientId",
                ClientSecret = "clientSecret",
                RedirectUri = "notCorrectRedirectUri"
            };

            var result = new AuthenticationResult(new Core.Common.Models.Client { ClientId = "clientId" }, null);
            var authorizationCode = new AuthorizationCode
            {
                ClientId = "clientId",
                RedirectUri = "redirectUri"
            };

            _clientValidatorFake.Setup(c => c.CheckPkce(It.IsAny<Client>(), It.IsAny<string>(), It.IsAny<AuthorizationCode>()))
                .Returns(true);
            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny<AuthenticationHeaderValue>()))
                .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny<AuthenticateInstruction>()))
                .Returns(Task.FromResult(result));
            _authorizationCodeStoreFake.Setup(a => a.GetAuthorizationCode(It.IsAny<string>()))
                .Returns(Task.FromResult(authorizationCode));

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync<IdentityServerException>(() =>
                _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null));
            Assert.True(exception.Code == ErrorCodes.InvalidGrant);
            Assert.True(exception.Message == ErrorDescriptions.TheRedirectionUrlIsNotTheSame);
        }
        public async Task When_Client_Cannot_Be_Authenticated_Then_Error_Is_Returned()
        {
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                Code                = "abc",
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId            = "clientId",
                ClientSecret        = "clientSecret"
            };

            _clientStore.Setup(x => x.GetById(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync((Client)null);

            var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                authorizationCodeGrantTypeParameter,
                null,
                null,
                null,
                CancellationToken.None)
                         .ConfigureAwait(false) as Option <GrantedToken> .Error;

            Assert.Equal(ErrorCodes.InvalidClient, result !.Details.Title);
        }
        public async Task When_Authorization_Code_Is_Not_Valid_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId            = "clientId",
                ClientSecret        = "clientSecret"
            };
            var client = new AuthenticationResult(new Client(), null);

            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>()))
            .Returns(() => Task.FromResult(client));
            _authorizationCodeRepositoryFake.Setup(a => a.GetAsync(It.IsAny <string>()))
            .Returns(() => Task.FromResult((AuthorizationCode)null));

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync <IdentityServerException>(() =>
                                                                               _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null));

            Assert.True(exception.Code == ErrorCodes.InvalidGrant);
            Assert.True(exception.Message == ErrorDescriptions.TheAuthorizationCodeIsNotCorrect);
        }
 public GrantTokenViaAuthorizationCodeReceived(string id, string processId, AuthorizationCodeGrantTypeParameter parameter, AuthenticationHeaderValue authHeader, int order)
 {
     Id         = id;
     ProcessId  = processId;
     Parameter  = parameter;
     Order      = order;
     AuthHeader = authHeader;
 }
        private AuthenticateInstruction CreateAuthenticateInstruction(
            AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
            AuthenticationHeaderValue authenticationHeaderValue)
        {
            var result = _authenticateInstructionGenerator.GetAuthenticateInstruction(authenticationHeaderValue);

            result.ClientAssertion                 = authorizationCodeGrantTypeParameter.ClientAssertion;
            result.ClientAssertionType             = authorizationCodeGrantTypeParameter.ClientAssertionType;
            result.ClientIdFromHttpRequestBody     = authorizationCodeGrantTypeParameter.ClientId;
            result.ClientSecretFromHttpRequestBody = authorizationCodeGrantTypeParameter.ClientSecret;
            return(result);
        }
Exemple #11
0
        public void When_Passing_EmptyCode_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObject();
            var parameter = new AuthorizationCodeGrantTypeParameter();

            // ACT & ASSERTS
            var exception = Assert.Throws <IdentityServerException>(() => _authorizationCodeGrantTypeParameterTokenEdpValidator.Validate(parameter));

            Assert.True(exception.Code == ErrorCodes.InvalidRequestCode);
            Assert.True(exception.Message == string.Format(ErrorDescriptions.MissingParameter, Constants.StandardTokenRequestParameterNames.AuthorizationCodeName));
        }
        public async Task When_RedirectUri_Is_Different_From_The_One_Hold_By_The_Client_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = "clientSecret",
                RedirectUri         = "redirectUri",
                ClientId            = "clientId",
            };
            var result = new AuthenticationResult(new Client
            {
                ClientId   = "clientId",
                GrantTypes = new System.Collections.Generic.List <GrantType>
                {
                    GrantType.authorization_code
                },
                ResponseTypes = new System.Collections.Generic.List <ResponseType>
                {
                    ResponseType.code
                }
            }, null);
            var authorizationCode = new AuthorizationCode
            {
                ClientId       = "clientId",
                RedirectUri    = "redirectUri",
                CreateDateTime = DateTime.UtcNow
            };

            _clientValidatorFake.Setup(c => c.CheckPkce(It.IsAny <Client>(), It.IsAny <string>(), It.IsAny <AuthorizationCode>()))
            .Returns(true);
            _authorizationCodeStoreFake.Setup(a => a.RemoveAuthorizationCode(It.IsAny <string>())).Returns(Task.FromResult(true));
            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>(), null, It.IsAny <bool>()))
            .Returns(Task.FromResult(result));
            _authorizationCodeStoreFake.Setup(a => a.GetAuthorizationCode(It.IsAny <string>()))
            .Returns(Task.FromResult(authorizationCode));
            _simpleIdentityServerConfiguratorFake.Setup(s => s.GetAuthorizationCodeValidityPeriodInSecondsAsync())
            .Returns(Task.FromResult((double)3000));
            _clientValidatorFake.Setup(c => c.GetRedirectionUrls(It.IsAny <Client>(), It.IsAny <string[]>()))
            .Returns(new string[0]);

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync <IdentityServerException>(() =>
                                                                               _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null, null, null));

            Assert.True(exception.Code == ErrorCodes.InvalidGrant);
            Assert.True(exception.Message == string.Format(ErrorDescriptions.RedirectUrlIsNotValid, "redirectUri"));
        }
        public async Task When_RedirectUri_Is_Different_From_The_One_Hold_By_The_Client_Then_Error_Is_Returned()
        {
            InitializeFakeObjects(TimeSpan.FromSeconds(3000));
            var clientId     = "clientId";
            var clientSecret = "clientSecret";
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                Code                = "abc",
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = clientSecret,
                RedirectUri         = new Uri("https://redirectUri"),
                ClientId            = clientId,
            };
            var client = new Client
            {
                RequirePkce = false,
                ClientId    = clientId,
                Secrets     = new[] { new ClientSecret {
                                          Type = ClientSecretTypes.SharedSecret, Value = clientSecret
                                      } },
                GrantTypes    = new[] { GrantTypes.AuthorizationCode },
                ResponseTypes = new[] { ResponseTypeNames.Code }
            };
            var authorizationCode = new AuthorizationCode
            {
                ClientId       = clientId,
                RedirectUri    = new Uri("https://redirectUri"),
                CreateDateTime = DateTimeOffset.UtcNow
            };

            _clientStore.Setup(x => x.GetById(It.IsAny <string>(), It.IsAny <CancellationToken>())).ReturnsAsync(client);
            _authorizationCodeStoreFake.Setup(a => a.Remove(It.IsAny <string>(), It.IsAny <CancellationToken>())).ReturnsAsync(true);
            _authorizationCodeStoreFake.Setup(a => a.Get(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(authorizationCode);

            var authenticationHeader = new AuthenticationHeaderValue(
                "Basic",
                $"{clientId}:{clientSecret}".Base64Encode());
            var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                authorizationCodeGrantTypeParameter,
                authenticationHeader,
                null,
                null,
                CancellationToken.None)
                         .ConfigureAwait(false) as Option <GrantedToken> .Error;

            Assert.Equal(ErrorCodes.InvalidRedirectUri, result.Details.Title);
            Assert.Equal(
                string.Format(Strings.RedirectUrlIsNotValid, "https://redirecturi/"),
                result.Details.Detail);
        }
        public async Task When_Granted_Client_Is_Not_The_Same_Then_Error_Is_Returned()
        {
            InitializeFakeObjects();
            var clientSecret = "clientSecret";
            var clientId     = "notCorrectClientId";
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                Code                = "abc",
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId            = clientId,
                ClientSecret        = clientSecret
            };

            var client = new Client
            {
                RequirePkce = false,
                ClientId    = clientId,
                Secrets     = new[] { new ClientSecret {
                                          Type = ClientSecretTypes.SharedSecret, Value = clientSecret
                                      } },
                GrantTypes    = new[] { GrantTypes.AuthorizationCode },
                ResponseTypes = new[] { ResponseTypeNames.Code }
            };
            var authorizationCode = new AuthorizationCode {
                ClientId = "clientId"
            };

            _clientStore.Setup(x => x.GetById(It.IsAny <string>(), It.IsAny <CancellationToken>())).ReturnsAsync(client);
            _authorizationCodeStoreFake.Setup(a => a.Get(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .Returns(() => Task.FromResult(authorizationCode));

            var authenticationHeader = new AuthenticationHeaderValue(
                "Basic",
                $"{clientId}:{clientSecret}".Base64Encode());
            var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                authorizationCodeGrantTypeParameter,
                authenticationHeader,
                null,
                null,
                CancellationToken.None)
                         .ConfigureAwait(false) as Option <GrantedToken> .Error;

            Assert.Equal(ErrorCodes.InvalidRequest, result.Details.Title);
            Assert.Equal(
                string.Format(
                    Strings.TheAuthorizationCodeHasNotBeenIssuedForTheGivenClientId,
                    "clientId"),
                result.Details.Detail);
        }
        public async Task When_The_Authorization_Code_Has_Expired_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = "clientSecret",
                RedirectUri         = "redirectUri",
                ClientId            = "clientId",
            };
            var result = new AuthenticationResult(new Core.Common.Models.Client
            {
                ClientId   = "clientId",
                GrantTypes = new System.Collections.Generic.List <GrantType>
                {
                    GrantType.authorization_code
                },
                ResponseTypes = new System.Collections.Generic.List <ResponseType>
                {
                    ResponseType.code
                }
            }, null);
            var authorizationCode = new AuthorizationCode
            {
                ClientId       = "clientId",
                RedirectUri    = "redirectUri",
                CreateDateTime = DateTime.UtcNow.AddSeconds(-30)
            };

            _clientValidatorFake.Setup(c => c.CheckPkce(It.IsAny <Core.Common.Models.Client>(), It.IsAny <string>(), It.IsAny <AuthorizationCode>()))
            .Returns(true);
            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>(), null))
            .Returns(Task.FromResult(result));
            _authorizationCodeStoreFake.Setup(a => a.GetAuthorizationCode(It.IsAny <string>()))
            .Returns(Task.FromResult(authorizationCode));
            _simpleIdentityServerConfiguratorFake.Setup(s => s.GetAuthorizationCodeValidityPeriodInSecondsAsync())
            .Returns(Task.FromResult((double)2));

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync <IdentityServerException>(() =>
                                                                               _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null, null, null));

            Assert.True(exception.Code == ErrorCodes.InvalidGrant);
            Assert.True(exception.Message == ErrorDescriptions.TheAuthorizationCodeIsObsolete);
        }
        public async Task When_The_Authorization_Code_Has_Expired_Then_Exception_Is_Thrown()
        {
            InitializeFakeObjects(TimeSpan.FromSeconds(2));
            var clientId     = "clientId";
            var clientSecret = "clientSecret";
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                Code                = "abc",
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = clientSecret,
                RedirectUri         = new Uri("https://redirectUri"),
                ClientId            = clientId,
            };
            var client = new Client
            {
                RequirePkce = false,
                ClientId    = clientId,
                Secrets     = new[] { new ClientSecret {
                                          Type = ClientSecretTypes.SharedSecret, Value = clientSecret
                                      } },
                GrantTypes    = new[] { GrantTypes.AuthorizationCode },
                ResponseTypes = new[] { ResponseTypeNames.Code }
            };
            var authorizationCode = new AuthorizationCode
            {
                ClientId       = clientId,
                RedirectUri    = new Uri("https://redirectUri"),
                CreateDateTime = DateTimeOffset.UtcNow.AddSeconds(-30)
            };

            _clientStore.Setup(x => x.GetById(It.IsAny <string>(), It.IsAny <CancellationToken>())).ReturnsAsync(client);
            _authorizationCodeStoreFake.Setup(a => a.Get(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(authorizationCode);

            var authenticationHeader = new AuthenticationHeaderValue(
                "Basic",
                $"{clientId}:{clientSecret}".Base64Encode());
            var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                authorizationCodeGrantTypeParameter,
                authenticationHeader,
                null,
                null,
                CancellationToken.None)
                         .ConfigureAwait(false) as Option <GrantedToken> .Error;

            Assert.Equal(ErrorCodes.ExpiredAuthorizationCode, result.Details.Title);
            Assert.Equal(Strings.TheAuthorizationCodeIsObsolete, result.Details.Detail);
        }
Exemple #17
0
        public void When_Passing_Invalid_RedirectUri_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObject();
            var parameter = new AuthorizationCodeGrantTypeParameter
            {
                Code        = "code",
                RedirectUri = "redirectUri"
            };

            // ACT & ASSERTS
            var exception = Assert.Throws <IdentityServerException>(() => _authorizationCodeGrantTypeParameterTokenEdpValidator.Validate(parameter));

            Assert.True(exception.Code == ErrorCodes.InvalidRequestCode);
            Assert.True(exception.Message == ErrorDescriptions.TheRedirectionUriIsNotWellFormed);
        }
        public async Task When_Granted_Client_Is_Not_The_Same_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId            = "notCorrectClientId",
                ClientSecret        = "clientSecret"
            };

            var result = new AuthenticationResult(new Client
            {
                ClientId   = "notCorrectClientId",
                GrantTypes = new System.Collections.Generic.List <GrantType>
                {
                    GrantType.authorization_code
                },
                ResponseTypes = new System.Collections.Generic.List <ResponseType>
                {
                    ResponseType.code
                }
            }, null);
            var authorizationCode = new AuthorizationCode
            {
                ClientId = "clientId"
            };

            _clientValidatorFake.Setup(c => c.CheckPkce(It.IsAny <Client>(), It.IsAny <string>(), It.IsAny <AuthorizationCode>()))
            .Returns(true);
            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>(), null, It.IsAny <bool>()))
            .Returns(() => Task.FromResult(result));
            _authorizationCodeStoreFake.Setup(a => a.GetAuthorizationCode(It.IsAny <string>()))
            .Returns(() => Task.FromResult(authorizationCode));

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync <IdentityServerException>(() =>
                                                                               _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null, null, null));

            Assert.True(exception.Code == ErrorCodes.InvalidGrant);
            Assert.True(exception.Message ==
                        string.Format(ErrorDescriptions.TheAuthorizationCodeHasNotBeenIssuedForTheGivenClientId,
                                      authorizationCodeGrantTypeParameter.ClientId));
        }
        public async Task <GrantedToken> Execute(
            AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
            AuthenticationHeaderValue authenticationHeaderValue)
        {
            if (authorizationCodeGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationCodeGrantTypeParameter));
            }

            var result = await ValidateParameter(
                authorizationCodeGrantTypeParameter,
                authenticationHeaderValue);

            // Invalidate the authorization code by removing it !
            await _authorizationCodeRepository.RemoveAsync(result.Code.Code);

            var grantedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(
                result.Code.Scopes,
                result.Code.ClientId,
                result.Code.IdTokenPayload,
                result.Code.UserInfoPayLoad);

            if (grantedToken == null)
            {
                grantedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(
                    result.Code.ClientId,
                    result.Code.Scopes,
                    result.Code.UserInfoPayLoad,
                    result.Code.IdTokenPayload);

                await _grantedTokenRepository.InsertAsync(grantedToken);

                _simpleIdentityServerEventSource.GrantAccessToClient(
                    result.Code.ClientId,
                    grantedToken.AccessToken,
                    grantedToken.IdToken);
            }

            // Fill-in the id-token
            if (grantedToken.IdTokenPayLoad != null)
            {
                grantedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(result.Client, grantedToken.IdTokenPayLoad);
            }

            return(grantedToken);
        }
        public async Task When_Client_Does_Not_Support_ResponseType_Code_Then_Error_Is_Returned()
        {
            InitializeFakeObjects();
            var clientId     = "clientId";
            var clientSecret = "clientSecret";
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                Code                = "abc",
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId            = clientId,
                ClientSecret        = clientSecret
            };
            var client = new Client
            {
                ResponseTypes = Array.Empty <string>(),
                ClientId      = clientId,
                Secrets       = new[] { new ClientSecret {
                                            Type = ClientSecretTypes.SharedSecret, Value = clientSecret
                                        } },
                GrantTypes = new[] { GrantTypes.AuthorizationCode }
            };

            _clientStore.Setup(x => x.GetById(It.IsAny <string>(), It.IsAny <CancellationToken>())).ReturnsAsync(client);

            var authenticationValue = new AuthenticationHeaderValue(
                "Basic",
                $"{clientId}:{clientSecret}".Base64Encode());
            var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                authorizationCodeGrantTypeParameter,
                authenticationValue,
                null,
                null,
                CancellationToken.None)
                         .ConfigureAwait(false) as Option <GrantedToken> .Error;

            Assert.Equal(ErrorCodes.InvalidResponse, result.Details.Title);
            Assert.Equal(
                string.Format(
                    Strings.TheClientDoesntSupportTheResponseType,
                    clientId,
                    ResponseTypeNames.Code),
                result.Details.Detail);
        }
        public async Task When_Pkce_Validation_Failed_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId            = "clientId",
                ClientSecret        = "clientSecret"
            };
            var authorizationCode = new AuthorizationCode
            {
                ClientId = "clientId"
            };
            var client = new AuthenticationResult(new Core.Common.Models.Client
            {
                ClientId   = "id",
                GrantTypes = new System.Collections.Generic.List <GrantType>
                {
                    GrantType.authorization_code
                },
                ResponseTypes = new System.Collections.Generic.List <ResponseType>
                {
                    ResponseType.code
                }
            }, null);

            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>(), null))
            .Returns(() => Task.FromResult(client));
            _authorizationCodeStoreFake.Setup(a => a.GetAuthorizationCode(It.IsAny <string>()))
            .Returns(() => Task.FromResult(authorizationCode));
            _clientValidatorFake.Setup(c => c.CheckPkce(It.IsAny <Core.Common.Models.Client>(), It.IsAny <string>(), It.IsAny <AuthorizationCode>()))
            .Returns(false);

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync <IdentityServerException>(() =>
                                                                               _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null, null, null));

            Assert.True(exception.Code == ErrorCodes.InvalidGrant);
            Assert.True(exception.Message == ErrorDescriptions.TheCodeVerifierIsNotCorrect);
        }
Exemple #22
0
        public void Validate(AuthorizationCodeGrantTypeParameter parameter)
        {
            if (string.IsNullOrWhiteSpace(parameter.Code))
            {
                throw new IdentityServerException(
                          ErrorCodes.InvalidRequestCode,
                          string.Format(ErrorDescriptions.MissingParameter, Constants.StandardTokenRequestParameterNames.AuthorizationCodeName));
            }

            // With this instruction
            // The redirect_uri is considered well-formed according to the RFC-3986
            var redirectUrlIsCorrect = Uri.IsWellFormedUriString(parameter.RedirectUri, UriKind.Absolute);

            if (!redirectUrlIsCorrect)
            {
                throw new IdentityServerException(
                          ErrorCodes.InvalidRequestCode,
                          ErrorDescriptions.TheRedirectionUriIsNotWellFormed);
            }
        }
Exemple #23
0
        public async Task <Option <GrantedToken> > GetTokenByAuthorizationCodeGrantType(
            AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
            AuthenticationHeaderValue?authenticationHeaderValue,
            X509Certificate2?certificate,
            string issuerName,
            CancellationToken cancellationToken)
        {
            var validation = Validate(authorizationCodeGrantTypeParameter);

            if (validation is Option.Error e)
            {
                return(e.Details);
            }

            return(await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                       authorizationCodeGrantTypeParameter,
                       authenticationHeaderValue,
                       certificate,
                       issuerName,
                       cancellationToken).ConfigureAwait(false));
        }
        public async Task When_Client_Cannot_Be_Authenticated_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientId = "clientId",
                ClientSecret = "clientSecret"
            };
            
            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny<AuthenticationHeaderValue>()))
                .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny<AuthenticateInstruction>()))
                .Returns(() => Task.FromResult(new AuthenticationResult(null, null)));

            // ACT & ASSERTS
            var exception = await Assert.ThrowsAsync<IdentityServerException>(() => 
                _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null));
            Assert.True(exception.Code == ErrorCodes.InvalidClient);
        }
Exemple #25
0
        public async Task <GrantedToken> Execute(AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName)
        {
            if (authorizationCodeGrantTypeParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationCodeGrantTypeParameter));
            }

            var result = await ValidateParameter(authorizationCodeGrantTypeParameter, authenticationHeaderValue, certificate, issuerName).ConfigureAwait(false);

            await _authorizationCodeStore.RemoveAuthorizationCode(result.AuthCode.Code); // 1. Invalidate the authorization code by removing it !

            var grantedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(
                result.AuthCode.Scopes,
                result.AuthCode.ClientId,
                result.AuthCode.IdTokenPayload,
                result.AuthCode.UserInfoPayLoad).ConfigureAwait(false);

            if (grantedToken == null)
            {
                grantedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(result.Client, result.AuthCode.Scopes, issuerName, result.AuthCode.UserInfoPayLoad, result.AuthCode.IdTokenPayload).ConfigureAwait(false);

                _oauthEventSource.GrantAccessToClient(
                    result.AuthCode.ClientId,
                    grantedToken.AccessToken,
                    grantedToken.IdToken);
                // Fill-in the id-token
                if (grantedToken.IdTokenPayLoad != null)
                {
                    await _jwtGenerator.UpdatePayloadDate(grantedToken.IdTokenPayLoad).ConfigureAwait(false);

                    grantedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(result.Client, grantedToken.IdTokenPayLoad).ConfigureAwait(false);
                }

                await _tokenStore.AddToken(grantedToken).ConfigureAwait(false);
            }

            return(grantedToken);
        }
        public string GetPayload(AuthorizationCodeGrantTypeParameter parameter, AuthenticationHeaderValue authenticationHeaderValue)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

            var clientId = GetClientId(authenticationHeaderValue);

            if (string.IsNullOrWhiteSpace(clientId))
            {
                clientId = parameter.ClientId;
            }

            var result = new Payload
            {
                ClientId      = clientId,
                Authorization = BuildAuthHeader(authenticationHeaderValue),
                Content       = parameter
            };

            return(JsonConvert.SerializeObject(result));
        }
        public async Task When_Requesting_An_Existed_Granted_Token_Then_Check_Id_Token_Is_Signed_And_Encrypted()
        {
            InitializeFakeObjects(TimeSpan.FromSeconds(3000));
            var handler     = new JwtSecurityTokenHandler();
            var accessToken = handler.CreateEncodedJwt(
                "test",
                "test",
                new ClaimsIdentity(),
                null,
                null,
                DateTime.Now,
                await _inMemoryJwksRepository.GetDefaultSigningKey().ConfigureAwait(false));
            const string identityToken = "identityToken";
            const string clientId      = "clientId";
            var          clientSecret  = "clientSecret";
            var          authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = clientSecret,
                RedirectUri         = new Uri("https://redirectUri"),
                ClientId            = clientId
            };

            var client = new Client
            {
                AllowedScopes   = new[] { "scope" },
                RedirectionUrls = new[] { new Uri("https://redirectUri") },
                ClientId        = clientId,
                Secrets         = new[] { new ClientSecret {
                                              Type = ClientSecretTypes.SharedSecret, Value = clientSecret
                                          } },
                GrantTypes                  = new[] { GrantTypes.AuthorizationCode },
                ResponseTypes               = new[] { ResponseTypeNames.Code },
                IdTokenSignedResponseAlg    = SecurityAlgorithms.RsaSha256,
                IdTokenEncryptedResponseAlg = SecurityAlgorithms.RsaPKCS1,
                IdTokenEncryptedResponseEnc = SecurityAlgorithms.Aes128CbcHmacSha256
            };
            var authorizationCode = new AuthorizationCode
            {
                ClientId       = clientId,
                RedirectUri    = new Uri("https://redirectUri"),
                CreateDateTime = DateTimeOffset.UtcNow,
                Scopes         = "scope"
            };
            var grantedToken = new GrantedToken
            {
                ClientId       = clientId,
                AccessToken    = accessToken,
                IdToken        = identityToken,
                IdTokenPayLoad = new JwtPayload(),
                CreateDateTime = DateTimeOffset.UtcNow,
                ExpiresIn      = 100000
            };

            _clientStore.Setup(x => x.GetById(It.IsAny <string>(), It.IsAny <CancellationToken>())).ReturnsAsync(client);

            _authorizationCodeStoreFake.Setup(a => a.Get(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(authorizationCode);

            _tokenStoreFake
            .Setup(
                x => x.GetToken(
                    It.IsAny <string>(),
                    It.IsAny <string>(),
                    It.IsAny <JwtPayload>(),
                    It.IsAny <JwtPayload>(),
                    It.IsAny <CancellationToken>()))
            .ReturnsAsync(grantedToken);
            var authenticationHeader = new AuthenticationHeaderValue(
                "Basic",
                $"{clientId}:{clientSecret}".Base64Encode());
            var r = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                authorizationCodeGrantTypeParameter,
                authenticationHeader,
                null,
                null,
                CancellationToken.None)
                    .ConfigureAwait(false);

            Assert.NotNull(r);
        }
        public async Task When_Requesting_Token_And_There_Is_No_Valid_Granted_Token_Then_Grant_A_New_One()
        {
            InitializeFakeObjects();

            const string clientId     = "clientId";
            var          clientSecret = "clientSecret";
            var          authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                Code                = "abc",
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = clientSecret,
                RedirectUri         = new Uri("https://redirectUri"),
                ClientId            = clientId
            };
            var client = new Client
            {
                RequirePkce     = false,
                ClientName      = clientId,
                RedirectionUrls = new[] { new Uri("https://redirectUri") },
                ClientId        = clientId,
                Secrets         = new[] { new ClientSecret {
                                              Type = ClientSecretTypes.SharedSecret, Value = clientSecret
                                          } },
                GrantTypes    = new[] { GrantTypes.AuthorizationCode },
                ResponseTypes = new[] { ResponseTypeNames.Code },
                JsonWebKeys   =
                    "supersecretlongkey".CreateJwk(JsonWebKeyUseNames.Sig, KeyOperations.Sign, KeyOperations.Verify)
                    .ToSet(),
                IdTokenSignedResponseAlg = SecurityAlgorithms.RsaSha256
            };
            var authorizationCode = new AuthorizationCode
            {
                Scopes         = "scope",
                ClientId       = clientId,
                RedirectUri    = new Uri("https://redirectUri"),
                CreateDateTime = DateTimeOffset.UtcNow
            };

            _clientStore.Setup(x => x.GetById(It.IsAny <string>(), It.IsAny <CancellationToken>())).ReturnsAsync(client);

            _authorizationCodeStoreFake.Setup(a => a.Get(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(authorizationCode);
            _simpleAuthOptions = new RuntimeSettings(authorizationCodeValidityPeriod: TimeSpan.FromSeconds(3000));

            _tokenStoreFake.Setup(
                x => x.GetToken(
                    It.IsAny <string>(),
                    It.IsAny <string>(),
                    It.IsAny <JwtPayload>(),
                    It.IsAny <JwtPayload>(),
                    It.IsAny <CancellationToken>()))
            .ReturnsAsync((GrantedToken)null);

            var authenticationHeader = new AuthenticationHeaderValue(
                "Basic",
                $"{clientId}:{clientSecret}".Base64Encode());
            var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(
                authorizationCodeGrantTypeParameter,
                authenticationHeader,
                null,
                null,
                CancellationToken.None)
                         .ConfigureAwait(false);

            _tokenStoreFake.Verify(g => g.AddToken(It.IsAny <GrantedToken>(), It.IsAny <CancellationToken>()));
            _eventPublisher.Verify(s => s.Publish(It.IsAny <TokenGranted>()));
        }
        /// <summary>
        /// Check the parameters based on the RFC : http://openid.net/specs/openid-connect-core-1_0.html#TokenRequestValidation
        /// </summary>
        /// <param name="authorizationCodeGrantTypeParameter"></param>
        /// <param name="authenticationHeaderValue"></param>
        /// <returns></returns>
        private async Task <ValidationResult> ValidateParameter(
            AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
            AuthenticationHeaderValue authenticationHeaderValue)
        {
            // 1. Authenticate the client
            var instruction = CreateAuthenticateInstruction(authorizationCodeGrantTypeParameter, authenticationHeaderValue);
            var authResult  = await _authenticateClient.AuthenticateAsync(instruction);

            var client = authResult.Client;

            if (client == null)
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage);
            }

            var authorizationCode = await _authorizationCodeRepository.GetAsync(authorizationCodeGrantTypeParameter.Code);

            // 2. Check if the authorization code is valid
            if (authorizationCode == null)
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant,
                                                  ErrorDescriptions.TheAuthorizationCodeIsNotCorrect);
            }

            // 3. Check PKCE
            if (!_clientValidator.CheckPkce(client, authorizationCodeGrantTypeParameter.CodeVerifier, authorizationCode))
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheCodeVerifierIsNotCorrect);
            }

            // 4. Ensure the authorization code was issued to the authenticated client.
            var authorizationClientId = authorizationCode.ClientId;

            if (authorizationClientId != client.ClientId)
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant,
                                                  string.Format(ErrorDescriptions.TheAuthorizationCodeHasNotBeenIssuedForTheGivenClientId,
                                                                client.ClientId));
            }

            if (authorizationCode.RedirectUri != authorizationCodeGrantTypeParameter.RedirectUri)
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant,
                                                  ErrorDescriptions.TheRedirectionUrlIsNotTheSame);
            }

            // 5. Ensure the authorization code is still valid.
            var authCodeValidity = await _configurationService.GetAuthorizationCodeValidityPeriodInSecondsAsync();

            var expirationDateTime = authorizationCode.CreateDateTime.AddSeconds(authCodeValidity);
            var currentDateTime    = DateTime.UtcNow;

            if (currentDateTime > expirationDateTime)
            {
                throw new IdentityServerException(ErrorCodes.InvalidGrant,
                                                  ErrorDescriptions.TheAuthorizationCodeIsObsolete);
            }

            // Ensure that the redirect_uri parameter value is identical to the redirect_uri parameter value.
            var redirectionUrl = _clientValidator.GetRedirectionUrls(client, authorizationCodeGrantTypeParameter.RedirectUri);

            if (!redirectionUrl.Any())
            {
                throw new IdentityServerException(
                          ErrorCodes.InvalidGrant,
                          string.Format(ErrorDescriptions.RedirectUrlIsNotValid, authorizationCodeGrantTypeParameter.RedirectUri));
            }

            return(new ValidationResult
            {
                Client = client,
                Code = authorizationCode
            });
        }
        public async Task When_Requesting_Token_And_There_Is_No_Valid_Granted_Token_Then_Grant_A_New_One()
        {
            // ARRANGE
            InitializeFakeObjects();
            const string accessToken   = "accessToken";
            const string identityToken = "identityToken";
            const string clientId      = "clientId";
            var          authorizationCodeGrantTypeParameter = new AuthorizationCodeGrantTypeParameter
            {
                ClientAssertion     = "clientAssertion",
                ClientAssertionType = "clientAssertionType",
                ClientSecret        = "clientSecret",
                RedirectUri         = "redirectUri",
                ClientId            = clientId
            };
            var authResult = new AuthenticationResult(new Models.Client
            {
                ClientId = clientId
            }, null);
            var authorizationCode = new AuthorizationCode
            {
                ClientId       = clientId,
                RedirectUri    = "redirectUri",
                CreateDateTime = DateTime.UtcNow
            };
            var grantedToken = new GrantedToken
            {
                AccessToken = accessToken,
                IdToken     = identityToken
            };

            _clientValidatorFake.Setup(c => c.CheckPkce(It.IsAny <Client>(), It.IsAny <string>(), It.IsAny <AuthorizationCode>()))
            .Returns(true);
            _authenticateInstructionGeneratorStub.Setup(a => a.GetAuthenticateInstruction(It.IsAny <AuthenticationHeaderValue>()))
            .Returns(new AuthenticateInstruction());
            _authenticateClientFake.Setup(a => a.AuthenticateAsync(It.IsAny <AuthenticateInstruction>()))
            .Returns(Task.FromResult(authResult));
            _authorizationCodeRepositoryFake.Setup(a => a.GetAsync(It.IsAny <string>()))
            .Returns(Task.FromResult(authorizationCode));
            _simpleIdentityServerConfiguratorFake.Setup(s => s.GetAuthorizationCodeValidityPeriodInSecondsAsync())
            .Returns(Task.FromResult((double)3000));
            _clientValidatorFake.Setup(c => c.GetRedirectionUrls(It.IsAny <Models.Client>(), It.IsAny <string>()))
            .Returns(new[] { "redirectUri" });
            _grantedTokenHelperStub.Setup(g => g.GetValidGrantedTokenAsync(It.IsAny <string>(),
                                                                           It.IsAny <string>(),
                                                                           It.IsAny <JwsPayload>(),
                                                                           It.IsAny <JwsPayload>()))
            .Returns(() => Task.FromResult((GrantedToken)null));
            _grantedTokenGeneratorHelperFake.Setup(g => g.GenerateTokenAsync(It.IsAny <string>(),
                                                                             It.IsAny <string>(),
                                                                             It.IsAny <JwsPayload>(),
                                                                             It.IsAny <JwsPayload>()))
            .Returns(Task.FromResult(grantedToken));;

            // ACT
            var result = await _getTokenByAuthorizationCodeGrantTypeAction.Execute(authorizationCodeGrantTypeParameter, null);

            // ASSERTS
            _grantedTokenRepositoryFake.Verify(g => g.InsertAsync(grantedToken));
            _simpleIdentityServerEventSourceFake.Verify(s => s.GrantAccessToClient(
                                                            clientId,
                                                            accessToken,
                                                            identityToken));
            Assert.True(result.AccessToken == accessToken);
        }