private static TokenManager GetTokenManager()
        {
            var options       = CreateOptions();
            var claimsManager = CreateClaimsManager(options);

            var factory                = new LoggerFactory();
            var protector              = new EphemeralDataProtectionProvider(factory).CreateProtector("test");
            var codeSerializer         = new TokenDataSerializer <AuthorizationCode>(options, ArrayPool <char> .Shared);
            var codeDataFormat         = new SecureDataFormat <AuthorizationCode>(codeSerializer, protector);
            var refreshTokenSerializer = new TokenDataSerializer <RefreshToken>(options, ArrayPool <char> .Shared);
            var refreshTokenDataFormat = new SecureDataFormat <RefreshToken>(refreshTokenSerializer, protector);

            var timeStampManager   = new TimeStampManager();
            var credentialsPolicy  = GetCredentialsPolicy(options, timeStampManager);
            var codeIssuer         = new AuthorizationCodeIssuer(claimsManager, codeDataFormat, new ProtocolErrorProvider());
            var accessTokenIssuer  = new JwtAccessTokenIssuer(claimsManager, credentialsPolicy, new JwtSecurityTokenHandler(), options);
            var idTokenIssuer      = new JwtIdTokenIssuer(claimsManager, credentialsPolicy, new JwtSecurityTokenHandler(), options);
            var refreshTokenIssuer = new RefreshTokenIssuer(claimsManager, refreshTokenDataFormat);

            return(new TokenManager(
                       codeIssuer,
                       accessTokenIssuer,
                       idTokenIssuer,
                       refreshTokenIssuer,
                       new ProtocolErrorProvider()));
        }
        public async Task AuthorizationCodeIssuer_IncludesAllRequiredData()
        {
            // Arrange
            var dataFormat       = GetDataFormat();
            var expectedDateTime = new DateTimeOffset(2000, 01, 01, 0, 0, 0, TimeSpan.FromHours(1));
            var timeManager      = GetTimeManager(expectedDateTime, expectedDateTime.AddHours(1), expectedDateTime);

            var issuer  = new AuthorizationCodeIssuer(GetClaimsManager(timeManager), dataFormat, new ProtocolErrorProvider());
            var context = GetTokenGenerationContext(
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "user") })),
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(IdentityServiceClaimTypes.ClientId, "clientId") })));

            context.InitializeForToken(TokenTypes.AuthorizationCode);

            // Act
            await issuer.CreateAuthorizationCodeAsync(context);

            // Assert
            Assert.NotNull(context.AuthorizationCode);
            var code = Assert.IsType <AuthorizationCode>(context.AuthorizationCode.Token);

            Assert.NotNull(code);
            Assert.NotNull(code.Id);
            Assert.Equal("user", code.UserId);
            Assert.Equal("clientId", code.ClientId);
            Assert.Equal("http://www.example.com/callback", code.RedirectUri);
            Assert.Equal(new[] { "openid" }, code.Scopes);
            Assert.Equal("asdf", code.Nonce);
            Assert.Equal(expectedDateTime, code.IssuedAt);
            Assert.Equal(expectedDateTime.AddHours(1), code.Expires);
            Assert.Equal(expectedDateTime, code.NotBefore);
        }
        public async Task AuthorizationCodeIssuer_Fails_IfUserIsMissingUserId()
        {
            // Arrange
            var dataFormat = GetDataFormat();
            var issuer     = new AuthorizationCodeIssuer(GetClaimsManager(), dataFormat, new ProtocolErrorProvider());
            var context    = GetTokenGenerationContext();

            context.InitializeForToken(TokenTypes.AuthorizationCode);

            // Act
            var exception = await Assert.ThrowsAsync <InvalidOperationException>(
                () => issuer.CreateAuthorizationCodeAsync(context));

            // Assert
            Assert.Equal($"Missing '{ClaimTypes.NameIdentifier}' claim from the user.", exception.Message);
        }
        public async Task AuthorizationCodeIssuer_Fails_IfApplicationIsMissingClientId()
        {
            // Arrange
            var dataFormat  = GetDataFormat();
            var options     = GetOptions();
            var timeManager = GetTimeManager();
            var issuer      = new AuthorizationCodeIssuer(GetClaimsManager(), dataFormat, new ProtocolErrorProvider());
            var context     = GetTokenGenerationContext(
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "user") })));

            context.InitializeForToken(TokenTypes.AuthorizationCode);

            // Act
            var exception = await Assert.ThrowsAsync <InvalidOperationException>(
                () => issuer.CreateAuthorizationCodeAsync(context));

            // Assert
            Assert.Equal($"Missing '{IdentityServiceClaimTypes.ClientId}' claim from the application.", exception.Message);
        }
        public async Task AuthorizationCodeIssuer_ProtectsAuthorizationCode()
        {
            // Arrange
            var dataFormat  = GetDataFormat();
            var options     = GetOptions();
            var timeManager = GetTimeManager();
            var issuer      = new AuthorizationCodeIssuer(GetClaimsManager(), dataFormat, new ProtocolErrorProvider());
            var context     = GetTokenGenerationContext(
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "user") })),
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(IdentityServiceClaimTypes.ClientId, "clientId") })));

            context.InitializeForToken(TokenTypes.AuthorizationCode);

            // Act
            await issuer.CreateAuthorizationCodeAsync(context);

            // Assert
            Assert.NotNull(context.AuthorizationCode);
            Assert.Equal("protected authorization code", context.AuthorizationCode.SerializedValue);
        }
        public async Task AuthorizationCodeIssuer_DoesNotIncludeNonceWhenAbsent()
        {
            // Arrange
            var dataFormat = GetDataFormat();
            var issuer     = new AuthorizationCodeIssuer(GetClaimsManager(), dataFormat, new ProtocolErrorProvider());
            var context    = GetTokenGenerationContext(
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "user") })),
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(IdentityServiceClaimTypes.ClientId, "clientId") })),
                nonce: null);

            context.InitializeForToken(TokenTypes.AuthorizationCode);

            // Act
            await issuer.CreateAuthorizationCodeAsync(context);

            // Assert
            Assert.NotNull(context.AuthorizationCode);
            var result = Assert.IsType <AuthorizationCode>(context.AuthorizationCode.Token);

            Assert.NotNull(result);
            Assert.Null(result.Nonce);
        }