{"id":2073,"date":"2019-04-10T10:03:01","date_gmt":"2019-04-10T09:03:01","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=2073"},"modified":"2019-11-26T10:05:01","modified_gmt":"2019-11-26T09:05:01","slug":"net-core-ldap-login-member-of-groups-check","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/net-core-ldap-login-member-of-groups-check\/","title":{"rendered":".Net core Ldap Login \/ Member of groups check"},"content":{"rendered":"\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Net.NetworkInformation;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Domain.Enums;\nusing Domain.Models;\nusing Domain.Ports;\nusing Domain.Ports.Secondary;\nusing Novell.Directory.Ldap;\n\nnamespace LDAPAdapter\n{\n    public class LDAPAdapter : ILDAPAdapter\n    {\n        public Task&lt;bool> Login(LoginCredentials credentials)\n        {\n            var sb = new StringBuilder();\n            var useSsl = true;\n            var config = DomainPorts.ConfigurationStore.GetConfig(ConfigurationType.AppConfig);\n            string ldapserver = config[\"ApiSettings:LDAPServer\"];\n            using (LdapConnection ldapconnection = new LdapConnection())\n            {\n                ldapconnection.Connect(ldapserver, 389);\n                ldapconnection.Bind(credentials.Username, credentials.Password);\n                if (useSsl)\n                {\n                    ldapConnection.UserDefinedServerCertValidationDelegate += (o, certificate, chain, errors) => true;\n                    ldapConnection.SecureSocketLayer = true;\n                }\n                ldapconnection.Bind(\"ldap_readonly\", \"password\");\n\n                try\n                {\n\n                    var searchConstraints = new LdapSearchConstraints\n                    {\n                        ReferralFollowing = true,\n                        TimeLimit = 10000\n                    };\n                    var userName = credentials.Username.Split('\\\\')[1];\n                    var searchResults = ldapconnection.Search(\"DC=company,DC=lan\", LdapConnection.SCOPE_SUB,\n                        \"(sAMAccountName=\" + EscapeLdapSearchFilterParam(userName) + \")\",\n                        null,\n                        false,\n                        searchConstraints);\n\n                    var entriesDN = new List&lt;string>();\n                    while (searchResults.hasMore())\n                    {\n                        var entry = searchResults.next();\n                        entriesDN.Add(entry.DN);\n                    }\n\n                    foreach (var ldapEntryDn in entriesDN)\n                    {\n                        var ldapEntry = ldapconnection.Read(ldapEntryDn);\n                        sb.AppendLine(ldapEntry.DN);\n                        foreach (var attributeObj in ldapEntry.getAttributeSet())\n                        {\n                            var attribute = (LdapAttribute) attributeObj;\n                            if (attribute.Name.Equals(\"memberOf\", StringComparison.OrdinalIgnoreCase))\n                            {\n                                foreach(var val in attribute.StringValueArray) {\n                                    sb.AppendLine($\"{attribute.Name}: {val}\");\n                                }\n                            }                            \n                            \/\/sb.AppendLine($\"{attribute.Name}: {attribute.StringValue}\");\n                        }\n                    }\n                }\n                catch (Exception ex)\n                {\n                    Console.WriteLine(ex.Message);\n                }\n                finally\n                {\n                    Console.WriteLine(sb.ToString());\n                }\n\n            }\n            return (Task.FromResult(true));\n        }\n\n        public static string EscapeLdapSearchFilterParam(string searchFilter) {\n            var escape = new StringBuilder();\n            foreach (var current in searchFilter)\n            {\n                switch (current) {\n                    case '\\\\': escape.Append(@\"\\5c\"); break;\n                    case '*': escape.Append(@\"\\2a\"); break;\n                    case '(': escape.Append(@\"\\28\"); break;\n                    case ')': escape.Append(@\"\\29\"); break;\n                    case '\\u0000': escape.Append(@\"\\00\"); break;\n                    case '\/': escape.Append(@\"\\2f\"); break;\n                    default: escape.Append(current); break;\n                }\n            }\n            return escape.ToString();\n        }\n\n        private static string GetSearchBase(string schemaDn)\n        {\n            return string.Join(',', ParseDnString(schemaDn)\n                .Where(x => x.Key.Equals(\"DC\", StringComparison.OrdinalIgnoreCase))\n                .Select(x => $\"{x.Key}={x.Value}\"));\n        }\n\n        private static string GetServerDomain(string schemaDn)\n        {\n            var invalidNames = new[] { \"lan\", \"com\" };\n            var dn = ParseDnString(schemaDn)\n                .Where(x => x.Key.Equals(\"DC\", StringComparison.OrdinalIgnoreCase))\n                .FirstOrDefault(x => x.Value.Length >= 3 &amp;&amp; !invalidNames.Contains(x.Value.ToLower()));\n            return dn.Value;\n        }\n\n        private static IEnumerable&lt;KeyValuePair&lt;string, string>> ParseDnString(string schemaDn)\n        {\n            var re = new Regex(\"([^,]*?)=([^,]+)\");\n            var dcs = re.Matches(schemaDn)\n                .Select(x => new KeyValuePair&lt;string, string>(x.Groups[1].Value, x.Groups[2].Value));\n            return dcs;\n        }\n\n\n        bool FindUserInGroup(LdapConnection ldapConnection, string userDn, string groupDn, int ldapTimeout)\n        {\n            var foundUser = false;\n            var names = new List&lt;string>();\n\n            var searchConstraints = new LdapSearchConstraints\n            {\n                ReferralFollowing = true,\n                TimeLimit = ldapTimeout\n            };\n            var searchResults = ldapConnection.Search(groupDn, LdapConnection.SCOPE_SUB,\n                                                      null, \/\/\"(sAMAccountName=\" + EscapeLdapSearchFilterParam(userName) + \")\",\n                                                      null,\n                                                      false,\n                                                      searchConstraints);\n\n            var entriesDn = new List&lt;string>();\n            while (searchResults.hasMore())\n            {\n                var entry = searchResults.next();\n                entriesDn.Add(entry.DN);\n            }\n            IEnumerator objClass = null;\n            foreach (var ldapEntryDn in entriesDn)\n            {\n                var isMember = false;\n                string memberName = null;\n                var isGroup = false;\n                var ldapEntry = ldapConnection.Read(ldapEntryDn);\n                foreach (var attributeObj in ldapEntry.getAttributeSet())\n                {\n                    var attribute = (LdapAttribute)attributeObj;\n\n                    if (!names.Contains(attribute.Name))\n                        names.Add(attribute.Name);\n\n                    if (attribute.Name.Equals(\"objectClass\", StringComparison.OrdinalIgnoreCase))\n                        objClass = attribute.StringValues;\n\n                    if (attribute.Name.Equals(\"member\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        isMember = true;\n                        foreach (string val in attribute.StringValueArray)\n                        {\n                            \/* Naam bewaren, het kan een groep zijn *\/\n                            memberName = val;\n                            if (val == userDn)\n                            {\n                                foundUser = true;\n                                break;\n                            }\n                        }\n                    }\n\n                    if (foundUser)\n                        break;\n                }\n\n                if (foundUser)\n                    break;\n\n\n                while (objClass != null &amp;&amp; objClass.MoveNext())\n                {\n                    string objectName = (string)objClass.Current;\n\n                    if (objectName.ToUpper().Equals(\"group\".ToUpper()) ||\n                        objectName.ToUpper().Equals(\"groupOfNames\".ToUpper()) ||\n                        objectName.ToUpper().Equals(\"groupOfUniqueNames\".ToUpper()) ||\n                        objectName.ToUpper().Equals(\"dynamicGroup\".ToUpper()) ||\n                        objectName.ToUpper().Equals(\"dynamicGroupAux\".ToUpper()))\n                        isGroup = true;\n                }\n\n                if (isGroup &amp;&amp; isMember)\n                {\n                    \/* recursie! *\/\n                    foundUser = FindUserInGroup(ldapConnection, userDn, memberName, ldapTimeout);\n                }\n            }\n            return (foundUser);\n        }\n\n        public Dictionary&lt;string, string> GetAllUsersInGroup(string groupName)\n        {\n            var result = new Dictionary&lt;string, string>();\n            var domain = LdapHelper.GetProp($\"{LdapSettingsSection}:Server\", string.Empty);\n\n            using (var principalContext = new PrincipalContext(ContextType.Domain, domain))\n            using (var group = GroupPrincipal.FindByIdentity(principalContext, groupName))\n            {\n                if (group == null)\n                    return result;\n\n                foreach (UserPrincipal user in group.GetMembers(true))\n                {\n                    \/\/user variable has the details about the user \n                    result.Add(user.EmployeeId, user.DisplayName);\n                }\n            }\n\n            return result;\n        }\n\n        UserRole GetRole(LdapConnection ldapConnection, string userDn, int ldapTimeout)\n        {\n            var config = DomainPorts.ConfigurationStore.GetConfig(ConfigurationType.AppConfig);\n\n            var groups = new List&lt;GroupRole>();\n\n            if (config.ContainsKey(\"ActiveDirectoryGroups:Administrator\") &amp;&amp; config[\"ActiveDirectoryGroups:Administrator\"] != null)\n                groups.Add(new GroupRole(config[\"ActiveDirectoryGroups:Administrator\"], UserRole.Administrator));\n\n            if (config.ContainsKey(\"ActiveDirectoryGroups:Installer\") &amp;&amp; config[\"ActiveDirectoryGroups:Installer\"] != null)\n                groups.Add(new GroupRole(config[\"ActiveDirectoryGroups:Installer\"], UserRole.Installer));\n\n            if (config.ContainsKey(\"ActiveDirectoryGroups:Logistician\") &amp;&amp; config[\"ActiveDirectoryGroups:Logistician\"] != null)\n                groups.Add(new GroupRole(config[\"ActiveDirectoryGroups:Logistician\"], UserRole.Logistician));\n\n            foreach (var groupRole in groups)\n            {\n                if (FindUserInGroup(ldapConnection, userDn, groupRole.Group, ldapTimeout))\n                {\n                    return groupRole.Role;\n                }\n            }\n\n            \/\/ if user not found in any group\n            return UserRole.Unknown;\n        }\n    }\n}<\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2073","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2073","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=2073"}],"version-history":[{"count":5,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2073\/revisions"}],"predecessor-version":[{"id":2942,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/2073\/revisions\/2942"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=2073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=2073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=2073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}