using LdapLoginLib.Data; using LdapLoginLib.Models; using System.DirectoryServices.Protocols; namespace LdapLoginLib { public class LDAP { private static readonly LdapConfig _ldap = new(); //public LDAP() //{ // _ldap = new LdapConfig(); //} public bool Login(string password, string? document = null, string? username = null, string? email = null) { using (LdapConnection ldapConnection = _ldap.Connection()) { try { UserInfo userInfo = GetUserInfo( document: document, username: username, email: email); //Si el usuario está inactivo... if (userInfo.Activo == false) return false; // Set LDAP connection options ldapConnection.SessionOptions.SecureSocketLayer = false; ldapConnection.AuthType = AuthType.Basic; ldapConnection.Credential = _ldap.UserCredentials(userInfo.Usuario!, password); // Attempt to bind (authenticate) the user ldapConnection.Bind(); return true; } catch (LdapException ldapEx) { //Console.WriteLine($"Authentication failed: {ldapEx.Message}"); throw new Exception(_getErrorMessage(ldapEx.ErrorCode, ldapEx.Message)); } catch { //Console.WriteLine($"An error occurred: {ex.Message}"); //throw new Exception($"Ocurrió un error: {ex.Message}"); throw; } } } public static UserInfo GetUserInfo(string? document = null, string? username = null, string? email = null) { if ( string.IsNullOrEmpty(document?.Trim()) && string.IsNullOrEmpty(username?.Trim()) && string.IsNullOrEmpty(email?.Trim()) ) { throw new Exception("Usuario, correo o documento son requeridos"); } #region Query String Builder var ldapFilterArgs = new List(); //uid=APPuser163,ou=services,o=unal.edu.co if (string.IsNullOrEmpty(document?.Trim()) == false) { ldapFilterArgs.Add($"(employeeNumber={document.Trim()})"); } if (string.IsNullOrEmpty(username?.Trim()) == false) { ldapFilterArgs.Add($"(uid={username.Trim()})"); } if (string.IsNullOrEmpty(email?.Trim()) == false) { ldapFilterArgs.Add($"(mail={email.Trim()})"); } //ldapFilter.Append("ou=People,o=unal.edu.co"); #endregion using (LdapConnection ldapConnection = _ldap.Connection()) { try { // Admin login ldapConnection.SessionOptions.SecureSocketLayer = false; ldapConnection.AuthType = AuthType.Basic; ldapConnection.Credential = _ldap.AdminCredential(); ldapConnection.Bind(); //Query string searchBase = $"o=unal.edu.co"; string[] attributesToReturn = { "uid", "employeeNumber", "cn", "givenName", "sn", "mail", "inetUserStatus", "o", "nuip" }; string ldapFilter = $"(&{String.Join("", ldapFilterArgs.ToArray())})"; SearchRequest searchRequest = new( searchBase, ldapFilter, SearchScope.Subtree, attributesToReturn ); searchRequest.SizeLimit = 1; // Buscar solo el primero SearchResponse searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest); if (searchResponse != null && searchResponse.Entries.Count > 0) { SearchResultEntry entry = searchResponse.Entries[0]; LdapUserInfo ldapUserInfo = new() { Uid = entry.Attributes["uid"]?[0].ToString(), EmployeeNumber = entry.Attributes["employeeNumber"]?[0].ToString(), Cn = entry.Attributes["cn"]?[0].ToString(), GivenName = entry.Attributes["givenName"]?[0].ToString(), Sn = entry.Attributes["sn"]?[0].ToString(), Mail = entry.Attributes["mail"]?[0].ToString(), InetUserStatus = entry.Attributes["inetUserStatus"][0].ToString(), O = entry.Attributes["o"]?[0].ToString(), MailAlternateAddress = entry.Attributes["mailAlternateAddress"]?[0].ToString(), //IsActive = entry.Attributes["uid"][0].ToString(), //NUIP = entry.Attributes["NUIP"]?[0].ToString(), }; ldapUserInfo.IsActive = _isActive(ldapUserInfo.InetUserStatus); return (UserInfo)ldapUserInfo; } else { throw new Exception("Usuario no encontrado o no se recuperaron datos."); } } catch (LdapException ldapEx) { Console.WriteLine($"Authentication failed: {ldapEx.Message}"); Console.WriteLine($"Authentication failed: {ldapEx.ErrorCode}"); Console.WriteLine($"Authentication failed: {ldapEx.ServerErrorMessage}"); throw new Exception(ldapEx.Message); } catch // (Exception ex) { //Console.WriteLine($"An error occurred: {ex.Message}"); //throw new Exception($"Ocurrió un error: {ex.Message}"); throw; } } } private static bool _isActive(string? inetUserStatus) { if (String.IsNullOrEmpty(inetUserStatus?.Trim()) == false) { return inetUserStatus.ToLower().Trim() == "active" ? true : false; } return false; } private static string _getErrorMessage(int errorCode, string errorMessage) { // Map LDAP error codes to error messages switch (errorCode) { case 49: return "Error de credenciales: nombre de usuario o contraseña incorrectos"; case 52: return "Error de autenticación: cuenta está deshabilitada"; case 81: return "Error de servidor: no disponible"; default: return errorMessage; } } } }