public async Task CanStoreComplexClient(NpgsqlClientStore store, Fixture fixture, string clientId)
            {
                // Given
                var client = new Client
                {
                    ClientId = clientId,
                    ClientSecrets = fixture.Create<List<Secret>>(),
                    Flow = Flows.AuthorizationCode,
                    Claims = new List<Claim> { new Claim(fixture.Create("type"), fixture.Create("value"))},
                    AccessTokenType = AccessTokenType.Jwt,
                    ClientUri = fixture.Create<string>(),
                    ClientName = fixture.Create<string>(),
                    RequireConsent = false,
                    LogoUri = fixture.Create<string>(),
                    Enabled = true,
                };

                // When
                await store.AddClientAsync(client);

                // Then
                var fromDb = await store.FindClientByIdAsync(clientId);
                fromDb.ShouldNotBe(null);

                fromDb.ClientId.ShouldBe(clientId);
                fromDb.ClientSecrets.Count.ShouldBe(client.ClientSecrets.Count);
                fromDb.Flow.ShouldBe(client.Flow);
                
            }
示例#2
0
        public static Token CreateAccessTokenLong(Client client, string subjectId, int lifetime, int count, params string[] scopes)
        {
            var claims = new List<Claim>
            {
                new Claim("client_id", client.ClientId),
                new Claim("sub", subjectId)
            };

            for (int i = 0; i < count; i++)
            {
                claims.Add(new Claim("junk", "x".Repeat(100)));
            }

            scopes.ToList().ForEach(s => claims.Add(new Claim("scope", s)));

            var token = new Token(Constants.TokenTypes.AccessToken)
            {
                Audience = "https://idsrv3.com/resources",
                Issuer = "https://idsrv3.com",
                Lifetime = lifetime,
                Claims = claims,
                Client = client
            };

            return token;
        }
        public async Task<IOpenIdClientRegistration> AddAsync(IOpenIdClientMetadata clientMetadata) {
            using (var db = new ClientConfigurationDbContext(options.ConnectionString, options.Schema)) {
                string clientId = await clientIdGenerator.GenerateClientIdAsync(db);
                
                var registration = new OpenIdClientRegistration(clientId) {
                    ClientIdIssuedAtUtc = DateTime.UtcNow
                };

                var client = new Client() {
                    ClientId = clientId,
                    ClientName = clientMetadata.ClientName,
                    RedirectUris = clientMetadata.RedirectUris.ToList(),
                    Flow = GetFlows(clientMetadata.ResponseTypes),
                    LogoUri = clientMetadata.LogoUri,
                    ClientUri = clientMetadata.ClientUri
                };

                if (IsSecretRequired(client.Flow)) {
                    var secret = await secretGenerator.GenerateSecretAsync(db);
                    
                    client.ClientSecrets = new List<Secret> { secret };

                    registration.ClientSecret = secret.Value;
                }
                
                var e = client.ToEntity();
                
                db.Clients.Add(e);
                               
                await db.SaveChangesAsync();
                
                return registration;
            }
        }
        private async Task When_refreshing_onetimeonly_absolute_token_then_raise_event_with_two_different_handlers()
        {
            // Given 
            var oldHandle = "old_handle";
            var client = new Client()
            {
                RefreshTokenUsage = TokenUsage.OneTimeOnly,
                RefreshTokenExpiration = TokenExpiration.Absolute
            };

            var refreshToken = new RefreshToken()
            {
                AccessToken = new Token("token_type")
                {
                    Client = new Client()
                }
            };

            // When
            await _defaultRefreshTokenService.UpdateRefreshTokenAsync(oldHandle, refreshToken, client);

            // Then
            _eventServiceMock.Verify(x => x.RaiseAsync<RefreshTokenRefreshDetails>(
                It.Is<Event<RefreshTokenRefreshDetails>>(p => p.Details.OldHandle == oldHandle && p.Details.NewHandle != p.Details.OldHandle)), Times.Once);
        }
        /// <summary>
        /// Creates the refresh token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="accessToken">The access token.</param>
        /// <param name="client">The client.</param>
        /// <returns>
        /// The refresh token handle
        /// </returns>
        public virtual async Task<string> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken, Client client)
        {
            Logger.Debug("Creating refresh token");

            int lifetime;
            if (client.RefreshTokenExpiration == TokenExpiration.Absolute)
            {
                Logger.Debug("Setting an absolute lifetime: " + client.AbsoluteRefreshTokenLifetime);
                lifetime = client.AbsoluteRefreshTokenLifetime;
            }
            else
            {
                Logger.Debug("Setting a sliding lifetime: " + client.SlidingRefreshTokenLifetime);
                lifetime = client.SlidingRefreshTokenLifetime;
            }

            var handle = CryptoRandom.CreateUniqueId();
            var refreshToken = new RefreshToken
            {
                CreationTime = DateTimeOffsetHelper.UtcNow,
                LifeTime = lifetime,
                AccessToken = accessToken,
                Subject = subject
            };

            await _store.StoreAsync(handle, refreshToken);

            await RaiseRefreshTokenIssuedEventAsync(handle, refreshToken);
            return handle;
        }
 public DefaultConsentServiceTests()
 {
     scopes = new List<string> { "read", "write" };
     client = new Client {ClientId = "client", AllowRememberConsent = true, RequireConsent = true};
     user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]{new Claim(Constants.ClaimTypes.Subject, "123")}, "password"));
     store = new InMemoryConsentStore();
     subject = new DefaultConsentService(store);
 }
        public override async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable<Scope> scopes, ValidatedRequest request)
        {
            var claims = await base.GetAccessTokenClaimsAsync(subject, client, scopes, request);

            var newClaims = claims.ToList();
            newClaims.Add(subject.FindFirst("account_store"));

            return newClaims;
        }
示例#8
0
        public Task <IdentityServer3.Core.Models.Client> FindClientByIdAsync(string clientId)
        {
            //var client = DummyClientStore().FirstOrDefault(c => c.ClientId == clientId);
            //return client;
            var client = _repo.GetClient(clientId);

            if (client != null)
            {
                var idClient = new IdentityServer3.Core.Models.Client
                {
                    AbsoluteRefreshTokenLifetime = client.AbsoluteRefreshTokenLifetime,
                    AccessTokenLifetime          = client.AccessTokenLifetime,
                    AccessTokenType = (AccessTokenType)client.AccessTokenType,
                    AllowAccessToAllCustomGrantTypes = client.AllowAccessToAllGrantTypes,
                    AllowAccessToAllScopes           = client.AllowAccessToAllScopes,
                    AllowClientCredentialsOnly       = client.AllowClientCredentialsOnly,
                    AllowRememberConsent             = client.AllowRememberConsent,
                    AlwaysSendClientClaims           = client.AlwaysSendClientClaims,
                    AuthorizationCodeLifetime        = client.AuthorizationCodeLifetime,
                    ClientId                         = client.ClientId,
                    ClientName                       = client.ClientName,
                    ClientUri                        = client.ClientUri,
                    Enabled                          = client.Enabled,
                    EnableLocalLogin                 = client.EnableLocalLogin,
                    Flow                             = (Flows)client.Flow,
                    IdentityTokenLifetime            = client.IdentityTokenLifetime,
                    IncludeJwtId                     = client.IncludeJwtId,
                    LogoUri                          = client.LogoUri,
                    LogoutSessionRequired            = client.LogoutSessionRequired,
                    LogoutUri                        = client.LogoutUri,
                    PrefixClientClaims               = client.PrefixClientClaims,
                    RefreshTokenExpiration           = (TokenExpiration)client.RefreshTokenExpiration,
                    RefreshTokenUsage                = (TokenUsage)client.RefreshTokenUsage,
                    RequireConsent                   = client.RequireConsent,
                    RequireSignOutPrompt             = client.RequireSignOutPrompt,
                    SlidingRefreshTokenLifetime      = client.SlidingRefreshTokenLifetime,
                    UpdateAccessTokenClaimsOnRefresh = client.UpdateAccessTokenOnRefresh,

                    AllowedScopes = client.ClientScopes.ToList(),
                    ClientSecrets = client.ClientSecrets.Select(s =>
                    {
                        return(new Secret(s.Value, s.Description, s.Expiration));
                    }).ToList(),
                    RedirectUris = client.ClientRedirectUris.Select(r => r.Uri).ToList(),
                    Claims       = client.ClientClaims.ToList()
                };
                //AllowedScopes = client.ClientScopes.Select(s => s.Scope).ToList(),
                //ClientSecrets = client.ClientSecrets.Select(s =>
                //{
                //    return new Secret(s.Value, s.Description, s.Expiration);
                //}).ToList(),
                //RedirectUris = client.ClientRedirectUris.Select(r => r.Uri).ToList(),

                return(Task.FromResult <IdentityServer3.Core.Models.Client>(idClient));
            }
            return(Task.FromResult <IdentityServer3.Core.Models.Client>(null));
        }
        public static IEnumerable<Client> Get()
        {
            var mvc = new Client
            {
                ClientName = "MVC Client",
                ClientId = "mvc",
                Flow = Flows.Implicit,

                RedirectUris = new List<string>
                {
                    "https://localhost:44346/"
                },

                AllowedScopes = new List<string>
                {
                    "openid",
                    "user_data",
                    "webapi"
                }
            };

            var angular = new Client
            {
                ClientName = "AngularJS Client",
                ClientId = "angular",
                Flow = Flows.Implicit,

                RedirectUris = new List<string>
                {
                    "https://localhost:44300/modal.html",
                    "https://localhost:44300/#/tokenReceived?x=x&"
                },

                AllowedCorsOrigins = new List<string>
                {
                    "https://localhost:44300"
                },

                PostLogoutRedirectUris = new List<string>
                {
                    "https://localhost:44300/"
                },

                AllowedScopes = new List<string>
                {
                    "openid",
                    "user_data",
                    "webapi"
                }
            };

            return new List<Client>
            {
                mvc,
                angular
            };
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="IsActiveContext"/> class.
        /// </summary>
        public IsActiveContext(ClaimsPrincipal subject, Client client)
        {
            if (subject == null) throw new ArgumentNullException("subject");
            if (client == null) throw new ArgumentNullException("client");

            Subject = subject;
            Client = client;
            
            IsActive = true;
        }
 protected async Task SaveAsync(Client client)
 {
     BsonDocument doc = new ClientSerializer().Serialize(client);
     IMongoCollection<BsonDocument> collection = _data.Database.GetCollection<BsonDocument>(Settings.ClientCollection);
     var result = await collection.ReplaceOneAsync(
         Filter.ById(client.ClientId),
         doc,
         PerformUpsert
         ).ConfigureAwait(false);
     Debug.WriteLine(result);
 }
示例#12
0
        public override async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable<Scope> scopes, ValidatedRequest request)
        {
            var claims = await base.GetAccessTokenClaimsAsync(subject, client, scopes, request);

            var newClaims = claims.ToList();
            newClaims.Add(subject.FindFirst(Constants.ClaimTypes.Name));
            newClaims.Add(subject.FindFirst(Constants.ClaimTypes.Email));
            //newClaims.Add(subject.FindFirst(Constants.ClaimTypes.PreferredUserName));

            return newClaims;
        }
示例#13
0
        public void TestAddClient()
        {
            var entity = new Client()
            {
                ClientId = "test",
                ClientName = "test2",
                AllowedScopes = new List<string> { "item1", "item2" },
                RedirectUris = new List<string> { "http://redirect1" },
                AccessTokenType = AccessTokenType.Jwt,
                Flow = Flows.ResourceOwner,
                ClientSecrets = new List<Secret> { new Secret("secret") }

            }.ToEntity();
            Assert.NotNull(entity);
        }
示例#14
0
        public static List<Client> Get()
        {
            var currentClient = new Client
            {
                ClientName = "Silicon-only Client",
                ClientId = "silicon",
                Enabled = true,
                AccessTokenType = AccessTokenType.Reference,

                Flow = Flows.ClientCredentials,

                ClientSecrets = new List<Secret>
                    {
                        new Secret("F621F470-9731-4A25-80EF-67A6F7C5F4B8".Sha256())
                    },

                AllowedScopes = new List<string>
                    {
                        "LeagueComparer"
                    }
            };

            var secondClient = new Client
            {
                ClientName = "Silicon on behalf of Carbon Client",
                ClientId = "carbon",
                Enabled = true,
                AccessTokenType = AccessTokenType.Reference,

                Flow = Flows.ResourceOwner,

                ClientSecrets = new List<Secret>
                {
                    new Secret("21B5F798-BE55-42BC-8AA8-0025B903DC3B".Sha256())
                },

                AllowedScopes = new List<string>
                {
                    "LeagueComparer"
                }
            };

            return new List<Client>
            {
                currentClient,
                secondClient
            };
        }
        public Task AddClientAsync(Client client)
        {
            Preconditions.IsNotNull(client, nameof(client));

            return _conn.ExecuteCommand(_insertQuery,
                async cmd =>
                {
                    string model = _serializer.Serialize(client);
                    cmd.Parameters.AddWithValue("client", client.ClientId);
                    cmd.Parameters.AddWithValue("model", model);

                    await cmd.ExecuteNonQueryAsync();

                    return true;
                });
        }
        public async Task<Dictionary<string, object>> ProcessAsync(string subject, IEnumerable<string> scopes, Client client)
        {
            Logger.Info("Creating userinfo response");
            var profileData = new Dictionary<string, object>();
            
            var requestedClaimTypes = await GetRequestedClaimTypesAsync(scopes);
            var principal = Principal.Create("UserInfo", new Claim("sub", subject));

            IEnumerable<Claim> profileClaims;
            if (requestedClaimTypes.IncludeAllClaims)
            {
                Logger.InfoFormat("Requested claim types: all");

                var context = new ProfileDataRequestContext(
                    principal, 
                    client, 
                    Constants.ProfileDataCallers.UserInfoEndpoint);

                await _users.GetProfileDataAsync(context);
                profileClaims = context.IssuedClaims;
            }
            else
            {
                Logger.InfoFormat("Requested claim types: {0}", requestedClaimTypes.ClaimTypes.ToSpaceSeparatedString());

                var context = new ProfileDataRequestContext(
                    principal,
                    client,
                    Constants.ProfileDataCallers.UserInfoEndpoint,
                    requestedClaimTypes.ClaimTypes);

                await _users.GetProfileDataAsync(context);
                profileClaims = context.IssuedClaims;
            }
            
            if (profileClaims != null)
            {
                profileData = profileClaims.ToClaimsDictionary();
                Logger.InfoFormat("Profile service returned to the following claim types: {0}", profileClaims.Select(c => c.Type).ToSpaceSeparatedString());
            }
            else
            {
                Logger.InfoFormat("Profile service returned no claims (null)");
            }

            return profileData;
        }
            public async Task CanStoreSimpleClient(NpgsqlClientStore store, string clientId)
            {
                // Given
                var client = new Client()
                {
                    ClientId = clientId
                };

                // When
                await store.AddClientAsync(client);

                // Then
                var fromDb = await store.FindClientByIdAsync(clientId);
                fromDb.ShouldNotBe(null);

                fromDb.ClientId.ShouldBe(client.ClientId);
            }
        public Task<TokenRevocationRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, Client client)
        {
            if (parameters == null) throw new ArgumentNullException("parameters");
            if (client == null) throw new ArgumentNullException("client");

            ////////////////////////////
            // make sure token is present
            ///////////////////////////
            var token = parameters.Get("token");
            if (token.IsMissing())
            {
                return Task.FromResult(new TokenRevocationRequestValidationResult
                {
                    IsError = true,
                    Error = Constants.TokenErrors.InvalidRequest
                });
            }

            var result = new TokenRevocationRequestValidationResult
            {
                IsError = false,
                Token = token
            };


            ////////////////////////////
            // check token type hint
            ///////////////////////////
            var hint = parameters.Get("token_type_hint");
            if (hint.IsPresent())
            {
                if (Constants.SupportedTokenTypeHints.Contains(hint))
                {
                    result.TokenTypeHint = hint;
                }
                else
                {
                    result.IsError = true;
                    result.Error = Constants.RevocationErrors.UnsupportedTokenType;
                }
            }

            return Task.FromResult(result);
        }
示例#19
0
        public static IdentityClient ToEntity(this IdentityServer3.Core.Models.Client s)
        {
            if (s == null)
            {
                return(null);
            }

            if (s.ClientSecrets == null)
            {
                s.ClientSecrets = new List <Secret>();
            }
            if (s.RedirectUris == null)
            {
                s.RedirectUris = new List <string>();
            }
            if (s.PostLogoutRedirectUris == null)
            {
                s.PostLogoutRedirectUris = new List <string>();
            }
            if (s.AllowedScopes == null)
            {
                s.AllowedScopes = new List <string>();
            }
            if (s.IdentityProviderRestrictions == null)
            {
                s.IdentityProviderRestrictions = new List <string>();
            }
            if (s.Claims == null)
            {
                s.Claims = new List <Claim>();
            }
            if (s.AllowedCustomGrantTypes == null)
            {
                s.AllowedCustomGrantTypes = new List <string>();
            }
            if (s.AllowedCorsOrigins == null)
            {
                s.AllowedCorsOrigins = new List <string>();
            }

            return(Config.CreateMapper().Map <IdentityServer3.Core.Models.Client, IdentityClient>(s));
        }
        public void CanSerializeAndDeserializeAClient()
        {
            var client = new Client{
                ClientId = "123", 
                Enabled = true,
                AbsoluteRefreshTokenLifetime = 5, 
                AccessTokenLifetime = 10, 
                AccessTokenType = AccessTokenType.Jwt, 
                AllowRememberConsent = true, 
                RedirectUris = new List<string>{"http://foo.com"}
            };
            var clientStore = new InMemoryClientStore(new Client[]{client});
            var converter = new ClientConverter(clientStore);

            var settings = new JsonSerializerSettings();
            settings.Converters.Add(converter);
            var json = JsonConvert.SerializeObject(client, settings);

            var result = JsonConvert.DeserializeObject<Client>(json, settings);
            Assert.Same(client, result);
        }
        public void AutomapperConfigurationIsValid()
        {
            IdentityServer3.Core.Models.Scope s = new IdentityServer3.Core.Models.Scope()
            {
            };
            var e = s.ToEntity();

            IdentityServer3.Core.Models.Client c = new IdentityServer3.Core.Models.Client()
            {
            };
            var e2 = c.ToEntity();

            IdentityServer3.EntityFramework.Entities.Scope s2 = new IdentityServer3.EntityFramework.Entities.Scope()
            {
                ScopeClaims = new HashSet<IdentityServer3.EntityFramework.Entities.ScopeClaim>(),
                ScopeSecrets = new HashSet<IdentityServer3.EntityFramework.Entities.ScopeSecret>(),
            };
            var m = s2.ToModel();

            Mapper.AssertConfigurationIsValid();
        }
示例#22
0
        public override async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(
           ClaimsPrincipal subject, Client client, 
           IEnumerable<Scope> scopes, ValidatedRequest request)
        {

            var claimsTask = base.GetAccessTokenClaimsAsync(subject, client, scopes, request);
            var data = new ProfileDataRequestContext(subject, client, null, new string[] { Constants.ClaimTypes.Role });
            var roleClaimsTask =  _users.GetProfileDataAsync(data); 


            var claims = await Task.WhenAll(claimsTask);
            List<IEnumerable<Claim>> lst = new List<IEnumerable<Claim>>();
            lst.AddRange(claims);

            await Task.WhenAll(roleClaimsTask);
            lst.Add(data.IssuedClaims);

            var outputClaims = lst.Where(result => result != null)
                .SelectMany(claimList => claimList).ToList();

            return outputClaims;
        }
        protected override void PreInit()
        {
            host.Scopes.Add(StandardScopes.OpenId);
            host.Clients.Add(client = new Client
            {
                Enabled = true,
                ClientId = client_id,
                ClientSecrets = new List<Secret>
                {
                    new Secret(client_secret)
                },

                Flow = Flows.AuthorizationCode,
                AllowAccessToAllScopes = true,

                RequireConsent = false,
                RedirectUris = new List<string>
                {
                    redirect_uri
                }
            });
        }
        public void AutomapperConfigurationIsValid()
        {
            IdentityServer3.Core.Models.Scope s = new IdentityServer3.Core.Models.Scope()
            {
            };
            var e = s.ToEntity();

            IdentityServer3.Core.Models.Client c = new IdentityServer3.Core.Models.Client()
            {
            };
            var e2 = c.ToEntity();

            IdentityServer3.EntityFramework.Entities.Scope s2 = new IdentityServer3.EntityFramework.Entities.Scope()
            {
                ScopeClaims  = new HashSet <IdentityServer3.EntityFramework.Entities.ScopeClaim>(),
                ScopeSecrets = new HashSet <IdentityServer3.EntityFramework.Entities.ScopeSecret>(),
            };
            var m = s2.ToModel();

            IdentityServer3.EntityFramework.Entities.EntitiesMap.Mapper.ConfigurationProvider.AssertConfigurationIsValid();
            IdentityServer3.Core.Models.EntitiesMap.Mapper.ConfigurationProvider.AssertConfigurationIsValid();
        }
示例#25
0
        public static IEnumerable<Client> Get()
        {
            var currentClient = new Client
            {
                Enabled = true,
                ClientName = "LeagueComparer",
                ClientId = "comparer",
                Flow = Flows.Implicit,

                RedirectUris = new List<string>
                {
                    "https://localhost:44319"
                },

                AllowAccessToAllScopes = true
            };

            return new List<Client>()
            {
                currentClient
            };
        }
        /// <summary>
        /// Checks if consent is required.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="subject">The user.</param>
        /// <param name="scopes">The scopes.</param>
        /// <returns>Boolean if consent is required.</returns>
        public virtual async Task<bool> RequiresConsentAsync(Client client, ClaimsPrincipal subject, IEnumerable<string> scopes)
        {
            if (client == null) throw new ArgumentNullException("client");
            if (subject == null) throw new ArgumentNullException("subject");

            if (!client.RequireConsent)
            {
                return false;
            }

            // TODO: validate that this is a correct statement
            if (!client.AllowRememberConsent)
            {
                return true;
            }

            if (scopes == null || !scopes.Any())
            {
                return false;
            }

            // we always require consent for offline access if
            // the client has not disabled RequireConsent 
            if (scopes.Contains(Constants.StandardScopes.OfflineAccess))
            {
                return true;
            }
            
            var consent = await _store.LoadAsync(subject.GetSubjectId(), client.ClientId);
            if (consent != null && consent.Scopes != null)
            {
                var intersect = scopes.Intersect(consent.Scopes);
                return !(scopes.Count() == intersect.Count());
            }

            return true;
        }
        /// <summary>
        /// Returns claims for an identity token
        /// </summary>
        /// <param name="subject">The subject</param>
        /// <param name="client">The client</param>
        /// <param name="scopes">The requested scopes</param>
        /// <param name="includeAllIdentityClaims">Specifies if all claims should be included in the token, or if the userinfo endpoint can be used to retrieve them</param>
        /// <param name="request">The raw request</param>
        /// <returns>
        /// Claims for the identity token
        /// </returns>
        public virtual async Task<IEnumerable<Claim>> GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable<Scope> scopes, bool includeAllIdentityClaims, ValidatedRequest request)
        {
            Logger.Info("Getting claims for identity token for subject: " + subject.GetSubjectId());

            var outputClaims = new List<Claim>(GetStandardSubjectClaims(subject));
            outputClaims.AddRange(GetOptionalClaims(subject));
            
            var additionalClaims = new List<string>();

            // if a include all claims rule exists, call the user service without a claims filter
            if (scopes.IncludesAllClaimsForUserRule(ScopeType.Identity))
            {
                Logger.Info("All claims rule found - emitting all claims for user.");

                var context = new ProfileDataRequestContext(
                    subject,
                    client,
                    Constants.ProfileDataCallers.ClaimsProviderIdentityToken);

                await _users.GetProfileDataAsync(context);
                
                var claims = FilterProtocolClaims(context.IssuedClaims);
                if (claims != null)
                {
                    outputClaims.AddRange(claims);
                }

                return outputClaims;
            }

            // fetch all identity claims that need to go into the id token
            foreach (var scope in scopes)
            {
                if (scope.Type == ScopeType.Identity)
                {
                    foreach (var scopeClaim in scope.Claims)
                    {
                        if (includeAllIdentityClaims || scopeClaim.AlwaysIncludeInIdToken)
                        {
                            additionalClaims.Add(scopeClaim.Name);
                        }
                    }
                }
            }

            if (additionalClaims.Count > 0)
            {
                var context = new ProfileDataRequestContext(
                    subject,
                    client,
                    Constants.ProfileDataCallers.ClaimsProviderIdentityToken,
                    additionalClaims);
                
                await _users.GetProfileDataAsync(context);

                var claims = FilterProtocolClaims(context.IssuedClaims);
                if (claims != null)
                {
                    outputClaims.AddRange(claims);
                }
            }

            return outputClaims;
        }
        /// <summary>
        /// Returns claims for an identity token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="client">The client.</param>
        /// <param name="scopes">The requested scopes.</param>
        /// <param name="request">The raw request.</param>
        /// <returns>
        /// Claims for the access token
        /// </returns>
        public virtual async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable<Scope> scopes, ValidatedRequest request)
        {
            // add client_id
            var outputClaims = new List<Claim>
            {
                new Claim(Constants.ClaimTypes.ClientId, client.ClientId),
            };

            // check for client claims
            if (client.Claims != null && client.Claims.Any())
            {
                if (subject == null || client.AlwaysSendClientClaims)
                {
                    foreach (var claim in client.Claims)
                    {
                        var claimType = claim.Type;

                        if (client.PrefixClientClaims)
                        {
                            claimType = "client_" + claimType;
                        }

                        outputClaims.Add(new Claim(claimType, claim.Value, claim.ValueType));
                    }
                }
            }

            // add scopes
            foreach (var scope in scopes)
            {
                outputClaims.Add(new Claim(Constants.ClaimTypes.Scope, scope.Name));
            }

            // a user is involved
            if (subject != null)
            {
                outputClaims.AddRange(GetStandardSubjectClaims(subject));
                outputClaims.AddRange(GetOptionalClaims(subject));

                // if a include all claims rule exists, call the user service without a claims filter
                if (scopes.IncludesAllClaimsForUserRule(ScopeType.Resource))
                {
                    var context = new ProfileDataRequestContext(
                    subject,
                    client,
                    Constants.ProfileDataCallers.ClaimsProviderAccessToken);

                    await _users.GetProfileDataAsync(context);

                    var claims = FilterProtocolClaims(context.IssuedClaims);
                    if (claims != null)
                    {
                        outputClaims.AddRange(claims);
                    }

                    return outputClaims;
                }


                // fetch all resource claims that need to go into the id token
                var additionalClaims = new List<string>();
                foreach (var scope in scopes)
                {
                    if (scope.Type == ScopeType.Resource)
                    {
                        if (scope.Claims != null)
                        {
                            foreach (var scopeClaim in scope.Claims)
                            {
                                additionalClaims.Add(scopeClaim.Name);
                            }
                        }
                    }
                }

                if (additionalClaims.Count > 0)
                {
                    var context = new ProfileDataRequestContext(
                    subject,
                    client,
                    Constants.ProfileDataCallers.ClaimsProviderAccessToken,
                    additionalClaims.Distinct());

                    await _users.GetProfileDataAsync(context);

                    var claims = FilterProtocolClaims(context.IssuedClaims);
                    if (claims != null)
                    {
                        outputClaims.AddRange(claims);
                    }
                }
            }

            return outputClaims;
        }
 public static StoredClient ToDbFormat(Client client)
 {
     return new StoredClient
     {
         Id = "clients/" + client.ClientId,
         ClientId = client.ClientId,
         Enabled = client.Enabled,
         AbsoluteRefreshTokenLifetime = client.AbsoluteRefreshTokenLifetime,
         AccessTokenLifetime = client.AccessTokenLifetime,
         AccessTokenType = client.AccessTokenType.ToString(),
         AllowAccessToAllCustomGrantTypes = client.AllowAccessToAllCustomGrantTypes,
         AllowAccessToAllScopes = client.AllowAccessToAllScopes,
         AllowClientCredentialsOnly = client.AllowClientCredentialsOnly,
         AllowRememberConsent = client.AllowRememberConsent,
         AllowedCorsOrigins = client.AllowedCorsOrigins,
         AllowedCustomGrantTypes = client.AllowedCustomGrantTypes,
         AllowedScopes = client.AllowedScopes,
         AlwaysSendClientClaims = client.AlwaysSendClientClaims,
         AuthorizationCodeLifetime = client.AuthorizationCodeLifetime,
         ClientName = client.ClientName,
         ClientUri = client.ClientUri,
         EnableLocalLogin = client.EnableLocalLogin,
         Flow = client.Flow.ToString(),
         IdentityProviderRestrictions = client.IdentityProviderRestrictions,
         IdentityTokenLifetime = client.IdentityTokenLifetime,
         IncludeJwtId = client.IncludeJwtId,
         LogoUri = client.LogoUri,
         LogoutSessionRequired = client.LogoutSessionRequired,
         LogoutUri = client.LogoutUri,
         PostLogoutRedirectUris = client.PostLogoutRedirectUris,
         PrefixClientClaims = client.PrefixClientClaims,
         RedirectUris = client.RedirectUris,
         RefreshTokenExpiration = client.RefreshTokenExpiration.ToString(),
         RefreshTokenUsage = client.RefreshTokenUsage.ToString(),
         RequireConsent = client.RequireConsent,
         RequireSignOutPrompt = client.RequireSignOutPrompt,
         SlidingRefreshTokenLifetime = client.SlidingRefreshTokenLifetime,
         UpdateAccessTokenClaimsOnRefresh = client.UpdateAccessTokenClaimsOnRefresh,
         ClientSecrets = (from s in client.ClientSecrets select StoredSecret.ToDbFormat(s)).ToList(),
         Claims = (from c in client.Claims select StoredClientClaim.ToDbFormat(c)).ToList()
     };
 }
        public DefaultRefreshTokenServiceTests()
        {
            originalNowFunc = DateTimeOffsetHelper.UtcNowFunc;
            DateTimeOffsetHelper.UtcNowFunc = () => UtcNow;

            roclient_absolute_refresh_expiration_one_time_only = new Client
            {
                ClientName = "Resource Owner Client",
                Enabled = true,
                ClientId = "roclient_absolute_refresh_expiration_one_time_only",
                ClientSecrets = new List<Secret>
                { 
                    new Secret("secret".Sha256())
                },

                Flow = Flows.ResourceOwner,

                RefreshTokenExpiration = TokenExpiration.Absolute,
                RefreshTokenUsage = TokenUsage.OneTimeOnly,
                AbsoluteRefreshTokenLifetime = 200
            };

            roclient_sliding_refresh_expiration_one_time_only = new Client
            {
                ClientName = "Resource Owner Client",
                Enabled = true,
                ClientId = "roclient_sliding_refresh_expiration_one_time_only",
                ClientSecrets = new List<Secret>
                { 
                    new Secret("secret".Sha256())
                },

                Flow = Flows.ResourceOwner,

                RefreshTokenExpiration = TokenExpiration.Sliding,
                RefreshTokenUsage = TokenUsage.OneTimeOnly,
                AbsoluteRefreshTokenLifetime = 10,
                SlidingRefreshTokenLifetime = 4
            };

            roclient_absolute_refresh_expiration_reuse = new Client
            {
                ClientName = "Resource Owner Client",
                Enabled = true,
                ClientId = "roclient_absolute_refresh_expiration_reuse",
                ClientSecrets = new List<Secret>
                { 
                    new Secret("secret".Sha256())
                },

                Flow = Flows.ResourceOwner,

                RefreshTokenExpiration = TokenExpiration.Absolute,
                RefreshTokenUsage = TokenUsage.ReUse,
                AbsoluteRefreshTokenLifetime = 200
            };

            refreshTokenStore = new InMemoryRefreshTokenStore();
            service = new DefaultRefreshTokenService(refreshTokenStore, new DefaultEventService());

            user = IdentityServerPrincipal.Create("bob", "Bob Loblaw");
        }
        Token CreateAccessToken(Client client, string subjectId, int lifetime, params string[] scopes)
        {
            var claims = new List<Claim> 
            {
                new Claim("client_id", client.ClientId),
                new Claim("sub", subjectId)
            };

            scopes.ToList().ForEach(s => claims.Add(new Claim("scope", s)));

            var token = new Token(Constants.TokenTypes.AccessToken)
            {
                Audience = "https://idsrv3.com/resources",
                Issuer = "https://idsrv3.com",
                Lifetime = lifetime,
                Claims = claims,
                Client = client
            };

            return token;
        }
        public async Task<IHttpActionResult> ProcessAsync(Client client, NameValueCollection parameters)
        {
            // validate the token request
            var requestResult = await _requestValidator.ValidateRequestAsync(parameters, client);

            if (requestResult.IsError)
            {
                return new RevocationErrorResult(requestResult.Error);
            }

            // revoke tokens
            if (requestResult.TokenTypeHint == Constants.TokenTypeHints.AccessToken)
            {
                await RevokeAccessTokenAsync(requestResult.Token, client);
            }
            else if (requestResult.TokenTypeHint == Constants.TokenTypeHints.RefreshToken)
            {
                await RevokeRefreshTokenAsync(requestResult.Token, client);
            }
            else
            {
                var found = await RevokeAccessTokenAsync(requestResult.Token, client);

                if (!found)
                {
                    await RevokeRefreshTokenAsync(requestResult.Token, client);
                }
            }

            return Ok();
        }
        // revoke refresh token only if it belongs to client doing the request
        private async Task<bool> RevokeRefreshTokenAsync(string handle, Client client)
        {
            var token = await _refreshTokens.GetAsync(handle);

            if (token != null)
            {
                if (token.ClientId == client.ClientId)
                {
                    await _refreshTokens.RevokeAsync(token.SubjectId, token.ClientId);
                    await _tokenHandles.RevokeAsync(token.SubjectId, token.ClientId);
                    await _events.RaiseTokenRevokedEventAsync(token.SubjectId, handle, Constants.TokenTypeHints.RefreshToken);
                }
                else
                {
                    var message = string.Format("Client {0} tried to revoke a refresh token belonging to a different client: {1}", client.ClientId, token.ClientId);
                    
                    Logger.Warn(message);
                    await RaiseFailureEventAsync(message);
                }

                return true;
            }

            return false;
        }