Scan Active Directory for User Information
Fighting with a way to automatically get a windows authenticated users information from Active Directory. Settled on the following methods.
Create a list of lookup functions for things to try
private static readonly IReadOnlyCollection<Func<IIdentity, User>> UserLookupFns = new List<Func<IIdentity, User>>
{
ident => ident.FromUserPrincipal(),
ident => ident.FromDirectoryEntry(),
ident => ident.NoDetails()
};
Use multiple strategies to get user information
public static User ToUser(this IIdentity identity)
{
foreach (var lookup in UserLookupFns)
{
var currentUser = lookup(identity) ?? new User();
if (!currentUser.IsEmpty())
{
return currentUser;
}
}
return identity.NoDetails();
}
From Directory Entries
private static User FromDirectoryEntry(this IIdentity identity)
{
var fullName = identity.UserProperty(@"fullname") ?? "";
if (string.IsNullOrEmpty(fullName))
{
return null;
}
return new User
{
Login = identity.Name,
FirstName = fullName.SplitOnWhiteSpace().FirstOrDefault() ?? "",
LastName = fullName.SplitOnWhiteSpace().LastOrDefault() ?? "",
AutoEnrolled = true,
Role = RoleActions.All().OrderBy(k => k.Key).FirstOrDefault().Key
};
}
private static string UserProperty(this IIdentity identity, string propertyName)
{
try
{
var userEntry = new DirectoryEntry($"WinNT://{identity.Domain()}/{identity.Login()},User");
if (!userEntry.Properties.Contains(propertyName))
{
return "";
}
return (string)userEntry.Properties[propertyName].Value;
}
catch (Exception exc)
{
typeof(UserExtensions).Log().Warn(exc);
}
return "";
}
From Active Directory query
private static User FromDomain(this IIdentity identity)
{
var username = identity.Login();
var domain = identity.Domain();
var domainContext = new PrincipalContext(ContextType.Domain, domain);
var current = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, username);
typeof(UserExtensions).Log().Debug($"Current user principal: {current.Dump()}");
return current.ToUser(identity.Name);
}
private static string Domain(this IIdentity identity)
{
var s = identity.Name;
var stop = s.IndexOf("\\\\", StringComparison.Ordinal);
return stop > -1 ? s.Substring(0, stop) : string.Empty;
}
private static string Login(this IIdentity identity)
{
var s = identity.Name;
var stop = s.IndexOf("\\\\", StringComparison.Ordinal);
return stop > -1 ? s.Substring(stop + 1, s.Length - stop - 1) : string.Empty;
}