Files
jdescopingtool/OLD/WebInterface/Helpers/LDAPHelper.cs
T
Joseph Doherty 26ff8d9b4f Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
2026-01-02 07:43:29 -05:00

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;
}
}
}