26ff8d9b4f
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
162 lines
6.4 KiB
C#
Executable File
162 lines
6.4 KiB
C#
Executable File
using System;
|
|
using System.DirectoryServices;
|
|
using System.Linq;
|
|
using DataModel.Models;
|
|
using NLog;
|
|
using SearchResult = System.DirectoryServices.SearchResult;
|
|
|
|
namespace WebInterface.Helpers
|
|
{
|
|
/// <summary>
|
|
/// LDAP server interface helper methods
|
|
/// </summary>
|
|
public class LDAPHelper
|
|
{
|
|
/// <summary>
|
|
/// LDAP user lookup format
|
|
/// </summary>
|
|
private const string LDAP_LOOKUP_FORMAT = "(sAMAccountName={0})";
|
|
|
|
/// <summary>
|
|
/// Shared logger instance
|
|
/// </summary>
|
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
|
|
/// <summary>
|
|
/// Authenticates the user's credentials against the given LDAP server
|
|
/// </summary>
|
|
/// <param name="username">LDAP username</param>
|
|
/// <param name="password">LDAP password</param>
|
|
/// <param name="serverURL">LDAP server URL</param>
|
|
/// <param name="ldapGroup">LDAP group to filter for</param>
|
|
/// <returns>Whether or not user's credentials are valid</returns>
|
|
public static bool Authenticate(string username, string password, string serverURL, string ldapGroup = null)
|
|
{
|
|
bool result = false;
|
|
|
|
try
|
|
{
|
|
//Form full LDAP URL
|
|
string ldapURL = $"LDAP://{serverURL}";
|
|
|
|
//Attempt to find entry
|
|
DirectoryEntry entry = new DirectoryEntry(ldapURL, username, password);
|
|
object val = entry.NativeObject;
|
|
|
|
result = true;
|
|
}
|
|
catch (Exception error)
|
|
{
|
|
//Log but do not forward error
|
|
logger.Error("Authenticate: failed to authenticate user '{0}' against LDAP server '{1}': {2}.", username, serverURL, error.Message);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if user is in given group
|
|
/// </summary>
|
|
/// <param name="username">LDAP username</param>
|
|
/// <param name="password">LDAP password</param>
|
|
/// <param name="serverURL">LDAP server URL</param>
|
|
/// <param name="ldapGroup">LDAP group to filter for</param>
|
|
/// <param name="ldapFilter">LDAP search filter</param>
|
|
/// <returns>Whether or not user belongs to given group</returns>
|
|
public static bool IsInGroup(string username, string password, string serverURL, string ldapGroup, string ldapFilter = LDAP_LOOKUP_FORMAT)
|
|
{
|
|
try
|
|
{
|
|
//Form full LDAP URL
|
|
string ldapURL = $"LDAP://{serverURL}";
|
|
|
|
//Create a LDAP searcher
|
|
DirectorySearcher searcher = new DirectorySearcher
|
|
{
|
|
SearchRoot = new DirectoryEntry(ldapURL, username, password),
|
|
Filter = string.Format(ldapFilter, username)
|
|
};
|
|
|
|
foreach (SearchResult searchResult in searcher.FindAll())
|
|
{
|
|
DirectoryEntry directoryEntry = searchResult.GetDirectoryEntry();
|
|
foreach (var groupName in directoryEntry.Properties["memberOf"])
|
|
{
|
|
if (string.Equals(groupName.ToString(), ldapGroup, StringComparison.CurrentCultureIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception error)
|
|
{
|
|
//Log but do not forward error
|
|
logger.Error("Authenticate: failed to authenticate user '{0}' against LDAP server '{1}': {2}.", username, serverURL, error.Message);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Searches LDAP server for matching entry
|
|
/// </summary>
|
|
/// <param name="serverURL">URL for LDAP server to search</param>
|
|
/// <param name="username">LDAP server binding username</param>
|
|
/// <param name="password">LDAP server binding password</param>
|
|
/// <param name="ldapFilter">LDAP search filter</param>
|
|
/// <returns>Collection of matching LDAP entries</returns>
|
|
public static LDAPEntry LookupUser(string username, string password, string serverURL, string ldapFilter = LDAP_LOOKUP_FORMAT)
|
|
{
|
|
LDAPEntry result = null;
|
|
|
|
//Form full LDAP URL
|
|
string ldapURL = $"LDAP://{serverURL}";
|
|
|
|
//Create a LDAP searcher
|
|
DirectorySearcher searcher = new DirectorySearcher
|
|
{
|
|
SearchRoot = new DirectoryEntry(ldapURL, username, password),
|
|
Filter = string.Format(ldapFilter, username)
|
|
};
|
|
|
|
//Loop through search results
|
|
foreach (SearchResult searchResult in searcher.FindAll())
|
|
{
|
|
//Parse the entry's details
|
|
result = new LDAPEntry()
|
|
{
|
|
DN = ExtractProperty(searchResult, "distinguishedName"),
|
|
Username = username.ToLower(),
|
|
FirstName = ExtractProperty(searchResult, "givenName"),
|
|
LastName = ExtractProperty(searchResult, "sn"),
|
|
EmailAddress = ExtractProperty(searchResult, "mail"),
|
|
Title = ExtractProperty(searchResult, "title")
|
|
};
|
|
|
|
if (string.IsNullOrEmpty(result.FirstName) && !string.IsNullOrEmpty(result.DisplayName))
|
|
{
|
|
result.FirstName = result.DisplayName;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(result.LastName) && !string.IsNullOrEmpty(result.DisplayName))
|
|
{
|
|
result.LastName = result.DisplayName;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extracts the specified property from the LDAP search result
|
|
/// </summary>
|
|
/// <param name="result">LDAP search result to parse property from</param>
|
|
/// <param name="key">Lookup key for property</param>
|
|
/// <returns>Property value if it exists, empty string if it does not exist</returns>
|
|
private static string ExtractProperty(SearchResult result, string key)
|
|
{
|
|
return result.Properties[key].Count > 0 ? (string)result.Properties[key][0] : string.Empty;
|
|
}
|
|
}
|
|
} |