2024-03-13 15:22:06 -05:00
|
|
|
|
using LdapLoginLib.Data;
|
|
|
|
|
using LdapLoginLib.Models;
|
2024-04-29 09:51:35 -05:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2024-03-13 15:22:06 -05:00
|
|
|
|
using System.DirectoryServices.Protocols;
|
|
|
|
|
|
|
|
|
|
namespace LdapLoginLib
|
|
|
|
|
{
|
|
|
|
|
public class LDAP
|
|
|
|
|
{
|
2024-04-09 15:06:26 -05:00
|
|
|
|
private static readonly LdapConfig _ldap = new();
|
2024-04-29 09:51:35 -05:00
|
|
|
|
private readonly ILogger<LDAP> _logger;
|
2024-03-13 16:33:44 -05:00
|
|
|
|
|
2024-04-29 09:51:35 -05:00
|
|
|
|
public LDAP(ILogger<LDAP> logger)
|
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
//_ldap = new LdapConfig();
|
|
|
|
|
}
|
2024-03-13 15:22:06 -05:00
|
|
|
|
|
|
|
|
|
public bool Login(string password, string? document = null, string? username = null, string? email = null)
|
|
|
|
|
{
|
|
|
|
|
|
2024-04-09 15:06:26 -05:00
|
|
|
|
using (LdapConnection ldapConnection = _ldap.Connection())
|
2024-03-13 15:22:06 -05:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
UserInfo userInfo = GetUserInfo(
|
|
|
|
|
document: document,
|
|
|
|
|
username: username,
|
|
|
|
|
email: email);
|
|
|
|
|
|
2024-04-29 09:51:35 -05:00
|
|
|
|
_logger.LogInformation("Ingreso: " + userInfo.NumeroDocumento + " - " + userInfo.Usuario + " - " + userInfo.Correo);
|
|
|
|
|
|
2024-03-13 15:22:06 -05:00
|
|
|
|
//Si el usuario está inactivo...
|
|
|
|
|
if (userInfo.Activo == false) return false;
|
|
|
|
|
|
|
|
|
|
// Set LDAP connection options
|
|
|
|
|
ldapConnection.SessionOptions.SecureSocketLayer = false;
|
|
|
|
|
ldapConnection.AuthType = AuthType.Basic;
|
2024-04-09 15:06:26 -05:00
|
|
|
|
ldapConnection.Credential = _ldap.UserCredentials(userInfo.Usuario!, password);
|
2024-03-13 15:22:06 -05:00
|
|
|
|
|
|
|
|
|
// Attempt to bind (authenticate) the user
|
|
|
|
|
ldapConnection.Bind();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (LdapException ldapEx)
|
|
|
|
|
{
|
|
|
|
|
//Console.WriteLine($"Authentication failed: {ldapEx.Message}");
|
2024-04-29 09:51:35 -05:00
|
|
|
|
_logger.LogError(ldapEx.ErrorCode + " // " + ldapEx.Message);
|
2024-03-13 15:22:06 -05:00
|
|
|
|
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<string>();
|
|
|
|
|
|
|
|
|
|
//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
|
|
|
|
|
|
2024-04-09 15:06:26 -05:00
|
|
|
|
using (LdapConnection ldapConnection = _ldap.Connection())
|
2024-03-13 15:22:06 -05:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// Admin login
|
|
|
|
|
ldapConnection.SessionOptions.SecureSocketLayer = false;
|
|
|
|
|
ldapConnection.AuthType = AuthType.Basic;
|
2024-04-09 15:06:26 -05:00
|
|
|
|
ldapConnection.Credential = _ldap.AdminCredential();
|
2024-03-13 15:22:06 -05:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|