using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using Domain.Enums;
using Domain.Models;
using Domain.Ports;
using Domain.Ports.Secondary;
using Novell.Directory.Ldap;
namespace LDAPAdapter
{
public class LDAPAdapter : ILDAPAdapter
{
public Task<bool> Login(LoginCredentials credentials)
{
var sb = new StringBuilder();
var useSsl = true;
var config = DomainPorts.ConfigurationStore.GetConfig(ConfigurationType.AppConfig);
string ldapserver = config["ApiSettings:LDAPServer"];
using (LdapConnection ldapconnection = new LdapConnection())
{
ldapconnection.Connect(ldapserver, 389);
ldapconnection.Bind(credentials.Username, credentials.Password);
if (useSsl)
{
ldapConnection.UserDefinedServerCertValidationDelegate += (o, certificate, chain, errors) => true;
ldapConnection.SecureSocketLayer = true;
}
ldapconnection.Bind("ldap_readonly", "password");
try
{
var searchConstraints = new LdapSearchConstraints
{
ReferralFollowing = true,
TimeLimit = 10000
};
var userName = credentials.Username.Split('\\')[1];
var searchResults = ldapconnection.Search("DC=company,DC=lan", LdapConnection.SCOPE_SUB,
"(sAMAccountName=" + EscapeLdapSearchFilterParam(userName) + ")",
null,
false,
searchConstraints);
var entriesDN = new List<string>();
while (searchResults.hasMore())
{
var entry = searchResults.next();
entriesDN.Add(entry.DN);
}
foreach (var ldapEntryDn in entriesDN)
{
var ldapEntry = ldapconnection.Read(ldapEntryDn);
sb.AppendLine(ldapEntry.DN);
foreach (var attributeObj in ldapEntry.getAttributeSet())
{
var attribute = (LdapAttribute) attributeObj;
if (attribute.Name.Equals("memberOf", StringComparison.OrdinalIgnoreCase))
{
foreach(var val in attribute.StringValueArray) {
sb.AppendLine($"{attribute.Name}: {val}");
}
}
//sb.AppendLine($"{attribute.Name}: {attribute.StringValue}");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine(sb.ToString());
}
}
return (Task.FromResult(true));
}
public static string EscapeLdapSearchFilterParam(string searchFilter) {
var escape = new StringBuilder();
foreach (var current in searchFilter)
{
switch (current) {
case '\\': escape.Append(@"\5c"); break;
case '*': escape.Append(@"\2a"); break;
case '(': escape.Append(@"\28"); break;
case ')': escape.Append(@"\29"); break;
case '\u0000': escape.Append(@"\00"); break;
case '/': escape.Append(@"\2f"); break;
default: escape.Append(current); break;
}
}
return escape.ToString();
}
private static string GetSearchBase(string schemaDn)
{
return string.Join(',', ParseDnString(schemaDn)
.Where(x => x.Key.Equals("DC", StringComparison.OrdinalIgnoreCase))
.Select(x => $"{x.Key}={x.Value}"));
}
private static string GetServerDomain(string schemaDn)
{
var invalidNames = new[] { "lan", "com" };
var dn = ParseDnString(schemaDn)
.Where(x => x.Key.Equals("DC", StringComparison.OrdinalIgnoreCase))
.FirstOrDefault(x => x.Value.Length >= 3 && !invalidNames.Contains(x.Value.ToLower()));
return dn.Value;
}
private static IEnumerable<KeyValuePair<string, string>> ParseDnString(string schemaDn)
{
var re = new Regex("([^,]*?)=([^,]+)");
var dcs = re.Matches(schemaDn)
.Select(x => new KeyValuePair<string, string>(x.Groups[1].Value, x.Groups[2].Value));
return dcs;
}
bool FindUserInGroup(LdapConnection ldapConnection, string userDn, string groupDn, int ldapTimeout)
{
var foundUser = false;
var names = new List<string>();
var searchConstraints = new LdapSearchConstraints
{
ReferralFollowing = true,
TimeLimit = ldapTimeout
};
var searchResults = ldapConnection.Search(groupDn, LdapConnection.SCOPE_SUB,
null, //"(sAMAccountName=" + EscapeLdapSearchFilterParam(userName) + ")",
null,
false,
searchConstraints);
var entriesDn = new List<string>();
while (searchResults.hasMore())
{
var entry = searchResults.next();
entriesDn.Add(entry.DN);
}
IEnumerator objClass = null;
foreach (var ldapEntryDn in entriesDn)
{
var isMember = false;
string memberName = null;
var isGroup = false;
var ldapEntry = ldapConnection.Read(ldapEntryDn);
foreach (var attributeObj in ldapEntry.getAttributeSet())
{
var attribute = (LdapAttribute)attributeObj;
if (!names.Contains(attribute.Name))
names.Add(attribute.Name);
if (attribute.Name.Equals("objectClass", StringComparison.OrdinalIgnoreCase))
objClass = attribute.StringValues;
if (attribute.Name.Equals("member", StringComparison.OrdinalIgnoreCase))
{
isMember = true;
foreach (string val in attribute.StringValueArray)
{
/* Naam bewaren, het kan een groep zijn */
memberName = val;
if (val == userDn)
{
foundUser = true;
break;
}
}
}
if (foundUser)
break;
}
if (foundUser)
break;
while (objClass != null && objClass.MoveNext())
{
string objectName = (string)objClass.Current;
if (objectName.ToUpper().Equals("group".ToUpper()) ||
objectName.ToUpper().Equals("groupOfNames".ToUpper()) ||
objectName.ToUpper().Equals("groupOfUniqueNames".ToUpper()) ||
objectName.ToUpper().Equals("dynamicGroup".ToUpper()) ||
objectName.ToUpper().Equals("dynamicGroupAux".ToUpper()))
isGroup = true;
}
if (isGroup && isMember)
{
/* recursie! */
foundUser = FindUserInGroup(ldapConnection, userDn, memberName, ldapTimeout);
}
}
return (foundUser);
}
public Dictionary<string, string> GetAllUsersInGroup(string groupName)
{
var result = new Dictionary<string, string>();
var domain = LdapHelper.GetProp($"{LdapSettingsSection}:Server", string.Empty);
using (var principalContext = new PrincipalContext(ContextType.Domain, domain))
using (var group = GroupPrincipal.FindByIdentity(principalContext, groupName))
{
if (group == null)
return result;
foreach (UserPrincipal user in group.GetMembers(true))
{
//user variable has the details about the user
result.Add(user.EmployeeId, user.DisplayName);
}
}
return result;
}
UserRole GetRole(LdapConnection ldapConnection, string userDn, int ldapTimeout)
{
var config = DomainPorts.ConfigurationStore.GetConfig(ConfigurationType.AppConfig);
var groups = new List<GroupRole>();
if (config.ContainsKey("ActiveDirectoryGroups:Administrator") && config["ActiveDirectoryGroups:Administrator"] != null)
groups.Add(new GroupRole(config["ActiveDirectoryGroups:Administrator"], UserRole.Administrator));
if (config.ContainsKey("ActiveDirectoryGroups:Installer") && config["ActiveDirectoryGroups:Installer"] != null)
groups.Add(new GroupRole(config["ActiveDirectoryGroups:Installer"], UserRole.Installer));
if (config.ContainsKey("ActiveDirectoryGroups:Logistician") && config["ActiveDirectoryGroups:Logistician"] != null)
groups.Add(new GroupRole(config["ActiveDirectoryGroups:Logistician"], UserRole.Logistician));
foreach (var groupRole in groups)
{
if (FindUserInGroup(ldapConnection, userDn, groupRole.Group, ldapTimeout))
{
return groupRole.Role;
}
}
// if user not found in any group
return UserRole.Unknown;
}
}
}
207300cookie-check.Net core Ldap Login / Member of groups check