using HRD.LDAPService.JWT; using System; using System.DirectoryServices.AccountManagement; using System.Linq; namespace HRD.LDAPService { public static class LdapAuthenticationService { private const string LDAP_DOMAIN = "dhr.local"; private static UserPrincipal GetUserPrincipal(string loginName, PrincipalContext principalContext) { try { UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, loginName); if (userPrincipal == null) { userPrincipal = UserPrincipal.FindByIdentity(principalContext, loginName); if (userPrincipal == null) { throw new Exception($"Can't find an user by name: '{loginName}'"); } } return userPrincipal; } catch (Exception ex) { throw new Exception($"Login failed wrong user credentials '{loginName}'", ex); } } /// /// Returns a User without LDAP user authentication /// /// /// public static LdapUser RenewIdentity(string token) { if (string.IsNullOrEmpty(token)) { throw new ArgumentNullException("Token is empty!"); } try { LdapUser ldapUserFromToken = JwtManager.DecryptTokenAsLdapUser(token); if (ldapUserFromToken == default) { throw new Exception($"Wrong token"); } using PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, LDAP_DOMAIN); ldapUserFromToken.IsValidatCredentials = true; UpdateLdapUserFromPrincipalContext(ref ldapUserFromToken, principalContext); return ldapUserFromToken; } catch (Exception ex) { throw new Exception($"Renew failed", ex); } } /// /// Returns a User without LDAP user authentication /// /// /// public static LdapUser RenewIdentity(LdapUser ldapUser) { if (ldapUser == default) { return default; } try { if (String.IsNullOrEmpty(ldapUser.LoginName)) { throw new Exception($"Renew Login failed empty user Loginname"); } LdapUser ldapUserFromToken = JwtManager.DecryptTokenAsLdapUser(ldapUser.Token); if (ldapUserFromToken == default) { throw new Exception($"Wrong token"); } if (!string.Equals(ldapUserFromToken.LoginName, ldapUser.LoginName, StringComparison.OrdinalIgnoreCase)) { throw new Exception($"Loginname and Token-Loginname are not the same"); } if (ldapUser.IsRealLDAPUser) { ldapUserFromToken.IsRealLDAPUser = ldapUser.IsRealLDAPUser; using PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, LDAP_DOMAIN); ldapUser.IsValidatCredentials = true; UpdateLdapUserFromPrincipalContext(ref ldapUserFromToken, principalContext); } else { ldapUserFromToken.IsRealLDAPUser = false; ldapUserFromToken.AddPasswordHash(ldapUser.PasswordHash); if (!string.Equals(ldapUserFromToken.PasswordHashShort, ldapUser.PasswordHashShort, StringComparison.OrdinalIgnoreCase)) { throw new Exception($"PasswordHashShort and Token-PasswordHashShortare not the same"); } ldapUserFromToken.IsValidatCredentials = !string.IsNullOrEmpty(ldapUserFromToken.PasswordHash); ldapUserFromToken.Enabled = ldapUserFromToken.IsValidatCredentials; ldapUserFromToken.BadLogonCount = ldapUserFromToken.IsValidatCredentials ? 0 : ldapUserFromToken.BadLogonCount + 1; //ldapUserFromToken.IsAccountLockedOut = ; //ldapUserFromToken.LdapName = ; //ldapUserFromToken.LdapSurname = ; //ldapUserFromToken.LdapGuid = ; //ldapUserFromToken.Email = ; //ldapUserFromToken.AccountLockoutTime = ; } return ldapUserFromToken; } catch (Exception ex) { throw new Exception($"Login failed wrong user credentials '{ldapUser.LoginName}'", ex); } } /// /// Returns a User after LDAP user authentication /// /// /// public static bool CheckAndUpdateIdentityWithPassword(LdapUser ldapUser) { if (ldapUser == default) { return false; } try { if (String.IsNullOrEmpty(ldapUser.LoginName)) { throw new Exception($"Login failed wrong user Loginname"); } if (!JwtTokenConfig.DeaktivateLDAP) { ldapUser.IsRealLDAPUser = true; using var principalContext = new PrincipalContext(ContextType.Domain, LDAP_DOMAIN); //Check PWD ldapUser.IsValidatCredentials = principalContext.ValidateCredentials(ldapUser.LoginName, ldapUser.Password); UpdateLdapUserFromPrincipalContext(ref ldapUser, principalContext); } else { ldapUser.IsRealLDAPUser = false; //ldapUser.AddPasswordHash(JWTCrypt.GenerateHashPassword(ldapUser.Password)); var hash = JWTCrypt.SHA512(ldapUser.Password); ldapUser.AddPasswordHash(hash); ldapUser.IsValidatCredentials = !string.IsNullOrEmpty(ldapUser.PasswordHash); if (ldapUser.IsValidatCredentials) { ldapUser.Enabled = true; ldapUser.BadLogonCount = 0; ldapUser.LastBadPasswordAttempt = null; } else { ldapUser.Enabled = false; ldapUser.BadLogonCount = +1; ldapUser.LastBadPasswordAttempt = DateTime.UtcNow; } //ldapUser.IsAccountLockedOut = ; //ldapUser.LdapName = ; //ldapUser.LdapSurname = ; //ldapUser.LdapGuid = ; //ldapUser.Email = ; //ldapUser.AccountLockoutTime = ; } return true; } catch (Exception ex) { ldapUser.IsValidatCredentials = false; throw new Exception($"Login failed wrong user credentials '{ldapUser.LoginName}'", ex); } } private static void UpdateLdapUserFromPrincipalContext(ref LdapUser ldapUser, PrincipalContext principalContext) { UserPrincipal userPrincipal = GetUserPrincipal(ldapUser.LoginName, principalContext); if (userPrincipal == default) { throw new Exception($"Renew Login failed wrong user credentials '{ldapUser.LoginName}'"); } ldapUser.IsAccountLockedOut = userPrincipal.IsAccountLockedOut(); ldapUser.BadLogonCount = userPrincipal.BadLogonCount; ldapUser.Enabled = userPrincipal.Enabled ?? false; ldapUser.LastBadPasswordAttempt = userPrincipal.LastBadPasswordAttempt; ldapUser.LdapName = userPrincipal.Name; ldapUser.LdapSurname = userPrincipal.Surname; ldapUser.LdapGuid = userPrincipal.Guid; ldapUser.Email = userPrincipal.EmailAddress; ldapUser.AccountLockoutTime = userPrincipal.AccountLockoutTime; ldapUser.RoleList = ldapUser.RoleList.Union(JWT.JwtTokenConfig.JwtRoleList).ToList(); if (ldapUser.RoleList?.Count > 0) { ldapUser = userPrincipal.Context.CheckAndAddGroupMembers(userPrincipal, ldapUser); } } } }