Beispiel #1
0
 /// <summary>
 /// Creates a new <see cref="LdapContext"/>.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="scheme"></param>
 /// <param name="options"></param>
 /// <param name="settings"></param>
 public LdapContext(
     HttpContext context,
     AuthenticationScheme scheme,
     NegotiateOptions options,
     LdapSettings settings)
     : base(context, scheme, options)
 {
     LdapSettings = settings;
 }
Beispiel #2
0
        public static async Task RetrieveClaimsAsync(LdapSettings settings, ClaimsIdentity identity, ILogger logger)
        {
            var user              = identity.Name;
            var userAccountName   = user.Substring(0, user.IndexOf('@'));
            var distinguishedName = settings.Domain.Split('.').Select(name => $"dc={name}").Aggregate((a, b) => $"{a},{b}");

            var filter         = $"(&(objectClass=user)(sAMAccountName={userAccountName}))"; // This is using ldap search query language, it is looking on the server for someUser
            var searchRequest  = new SearchRequest(distinguishedName, filter, SearchScope.Subtree, null);
            var searchResponse = (SearchResponse)await Task <DirectoryResponse> .Factory.FromAsync(
                settings.LdapConnection.BeginSendRequest,
                settings.LdapConnection.EndSendRequest,
                searchRequest,
                PartialResultProcessing.NoPartialResultSupport,
                null);

            if (searchResponse.Entries.Count > 0)
            {
                if (searchResponse.Entries.Count > 1)
                {
                    logger.LogWarning($"More than one response received for query: {filter} with distinguished name: {distinguishedName}");
                }

                var userFound = searchResponse.Entries[0];        //Get the object that was found on ldap
                var memberof  = userFound.Attributes["memberof"]; // You can access ldap Attributes with Attributes property

                foreach (var group in memberof)
                {
                    // Example distinguished name: CN=TestGroup,DC=KERB,DC=local
                    var groupDN = $"{Encoding.UTF8.GetString((byte[])group)}";
                    var groupCN = groupDN.Split(',')[0].Substring("CN=".Length);

                    if (!settings.IgnoreNestedGroups)
                    {
                        GetNestedGroups(settings.LdapConnection, identity, distinguishedName, groupCN, logger);
                    }
                    else
                    {
                        AddRole(identity, groupCN);
                    }
                }
            }
            else
            {
                logger.LogWarning($"No response received for query: {filter} with distinguished name: {distinguishedName}");
            }
        }
Beispiel #3
0
        public static async Task RetrieveClaimsAsync(LdapSettings settings, ClaimsIdentity identity, ILogger logger)
        {
            var user = identity.Name !;
            var userAccountNameIndex = user.IndexOf('@');
            var userAccountName      = userAccountNameIndex == -1 ? user : user.Substring(0, userAccountNameIndex);

            if (settings.ClaimsCache == null)
            {
                settings.ClaimsCache = new MemoryCache(new MemoryCacheOptions {
                    SizeLimit = settings.ClaimsCacheSize
                });
            }

            if (settings.ClaimsCache.TryGetValue <IEnumerable <string> >(user, out var cachedClaims))
            {
                foreach (var claim in cachedClaims)
                {
                    identity.AddClaim(new Claim(identity.RoleClaimType, claim));
                }

                return;
            }

            var distinguishedName = settings.Domain.Split('.').Select(name => $"dc={name}").Aggregate((a, b) => $"{a},{b}");
            var retrievedClaims   = new List <string>();

            var filter        = $"(&(objectClass=user)(sAMAccountName={userAccountName}))"; // This is using ldap search query language, it is looking on the server for someUser
            var searchRequest = new SearchRequest(distinguishedName, filter, SearchScope.Subtree, null);

            Debug.Assert(settings.LdapConnection != null);
            var searchResponse = (SearchResponse)await Task <DirectoryResponse> .Factory.FromAsync(
                settings.LdapConnection.BeginSendRequest,
                settings.LdapConnection.EndSendRequest,
                searchRequest,
                PartialResultProcessing.NoPartialResultSupport,
                null);

            if (searchResponse.Entries.Count > 0)
            {
                if (searchResponse.Entries.Count > 1)
                {
                    logger.LogWarning($"More than one response received for query: {filter} with distinguished name: {distinguishedName}");
                }

                var userFound = searchResponse.Entries[0];        //Get the object that was found on ldap
                var memberof  = userFound.Attributes["memberof"]; // You can access ldap Attributes with Attributes property

                foreach (var group in memberof)
                {
                    // Example distinguished name: CN=TestGroup,DC=KERB,DC=local
                    var groupDN = $"{Encoding.UTF8.GetString((byte[])group)}";
                    var groupCN = groupDN.Split(',')[0].Substring("CN=".Length);

                    if (!settings.IgnoreNestedGroups)
                    {
                        GetNestedGroups(settings.LdapConnection, identity, distinguishedName, groupCN, logger, retrievedClaims);
                    }
                    else
                    {
                        retrievedClaims.Add(groupCN);
                    }
                }

                var entrySize = user.Length * 2; //Approximate the size of stored key in memory cache.
                foreach (var claim in retrievedClaims)
                {
                    identity.AddClaim(new Claim(identity.RoleClaimType, claim));
                    entrySize += claim.Length * 2; //Approximate the size of stored value in memory cache.
                }

                settings.ClaimsCache.Set(user,
                                         retrievedClaims,
                                         new MemoryCacheEntryOptions()
                                         .SetSize(entrySize)
                                         .SetSlidingExpiration(settings.ClaimsCacheSlidingExpiration)
                                         .SetAbsoluteExpiration(settings.ClaimsCacheAbsoluteExpiration));
            }
            else
            {
                logger.LogWarning($"No response received for query: {filter} with distinguished name: {distinguishedName}");
            }
        }