Hello, I already tried that, but I get: “VoloLdapExternalLoginProvider.CreateUserIfNotExistsAsync(string, string, ExternalLoginUserInfo)”: No suitable method for overwriting was found.
using AbelSystems_QMP.Security;
using LdapForNet;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Features;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.Identity.ExternalLoginProviders.Ldap;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Settings;
namespace AbelSystems_QMP.LDAP
{
public class VoloLdapExternalLoginProvider : LdapExternalLoginProvider
{
private readonly VoloOpenLdapManager _ldapManager;
private readonly QMPLdapSettingProvider _qmpLdapSettingProvider;
private readonly ILDAPAppService _ldapLoginAppService;
public VoloLdapExternalLoginProvider(
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant,
IdentityUserManager userManager,
IIdentityUserRepository identityUserRepository,
OpenLdapManager ldapManager,
QMPLdapSettingProvider qmpLdapSettingProvider,
IFeatureChecker featureChecker,
ISettingProvider settingProvider,
IOptions<IdentityOptions> identityOptions,
ILDAPAppService ldapLoginAppService)
: base(guidGenerator,
currentTenant,
userManager,
identityUserRepository,
ldapManager,
qmpLdapSettingProvider,
featureChecker,
settingProvider,
identityOptions)
{
_ldapManager = (VoloOpenLdapManager)ldapManager;
_qmpLdapSettingProvider = qmpLdapSettingProvider;
_ldapLoginAppService = ldapLoginAppService;
}
protected override Task<string> NormalizeUserNameAsync(string userName)
{
return Task.FromResult(userName);
}
protected override async Task<ExternalLoginUserInfo> GetUserInfoAsync(IdentityUser user)
{
var userInfo = await base.GetUserInfoAsync(user);
return userInfo;
}
protected override async Task<ExternalLoginUserInfo> GetUserInfoAsync(string userName)
{
var entry = await _ldapManager.FindUserAsync(userName);
if (entry == null)
{
throw new Exception($"LDAP user '{userName}' not found.");
}
var attr = entry.DirectoryAttributes;
// Felder dynamisch laden
var emailField = await _qmpLdapSettingProvider.GetEmailFieldAsync();
var givenNameField = await _qmpLdapSettingProvider.GetGivenNameFieldAsync();
var surnameField = await _qmpLdapSettingProvider.GetSurnameFieldAsync();
var departmentField = await _qmpLdapSettingProvider.GetAbteilungFieldAsync();
var phoneField = await _qmpLdapSettingProvider.GetTelefongFieldAsync();
var rolesField = await _qmpLdapSettingProvider.GetRoleFieldAsync();
// Dynamisch auslesen
var email = TryGetAttrValue(attr, emailField);
var givenName = TryGetAttrValue(attr, givenNameField);
var surname = TryGetAttrValue(attr, surnameField);
var department = TryGetAttrValue(attr, departmentField);
var phone = TryGetAttrValue(attr, phoneField);
var memberOf = TryGetAttrValues(attr, rolesField);
var roleNames = memberOf
.Select(dn => dn.Split(',').FirstOrDefault(x => x.StartsWith("CN=", StringComparison.InvariantCultureIgnoreCase)))
.Where(cn => cn != null)
.Select(cn => cn!.Substring(3)) // "CN=QM-Leitung" → "QM-Leitung"
.Distinct()
.ToList();
var userInfo = new QMPExternalLoginUserInfo(email ?? $"{userName}@unknown.local")
{
Name = givenName,
Surname = surname+"XX",
Department = department,
PhoneNumber = phone,
PhoneNumberConfirmed = true,
EmailConfirmed = true,
LdapRoles = roleNames,
};
return userInfo;
}
private static List<string> TryGetAttrValues(SearchResultAttributeCollection attr, string key)
{
return attr.TryGetValue(key, out var val)
? val.GetValues<string>().ToList()
: new List<string>();
}
private static string? TryGetAttrValue(SearchResultAttributeCollection attr, string key)
{
return attr.TryGetValue(key, out var val) ? val.GetValue<string>() : null;
}
public override async Task<bool> TryAuthenticateAsync(string userName, string plainPassword)
{
var ldapValid = await LdapManager.AuthenticateAsync(userName, plainPassword);
if (!ldapValid)
{
return false; // Kein Login, kein Benutzer
}
var userInfo = await GetUserInfoAsync(userName) as QMPExternalLoginUserInfo;
if (userInfo == null)
{
return false; // Kein Benutzerinfo, kein Login
}
// Optional: Existiert schon?
// Jetzt selbst anlegen
var dto = new QMPExternalLoginUserInfoDto
{
Email = userInfo.Email,
Name = userInfo.Name+"YYYY",
Surname = userInfo.Surname,
Department = userInfo.Department,
Phone = userInfo.PhoneNumber,
LdapRoles = userInfo.LdapRoles
};
var userDto = await _ldapLoginAppService.CreateOrUpdateFromExternalAsync(dto);
if (userDto == null)
{
Logger.LogInformation("Login unterdrückt – kein Benutzer angelegt.");
return false;
}
// Benutzer existiert → ABP loggt ihn automatisch ein
return true;
}
protected override Task<ExternalLoginUserInfo> CreateUserIfNotExistsAsync(string userName,string providerName,ExternalLoginUserInfo externalUser)
{
// Prevent automatic user creation
// Optionally, throw a custom exception or return null
return Task.FromResult<ExternalLoginUserInfo>(null);
}
//protected override async Task<ExternalLoginUserInfo> GetUserInfoAsync(string userName)
//{
// return await base.GetUserInfoAsync(userName);
//}
}
}
Uwe
Hello, We use: https://abp.io/docs/commercial/5.0/modules/account/ldap
However, I have to adapt and expand this. In general, it all works. However, I would like to create the users myself and** I need to be able to deactivate the automatic creation of LDAP users in ABP.** I can't find a way to disable the behavior of the Account Pro module to create new users.
Currently I create my user in the VoloLdapExternalLoginProvider TryAuthenticateAsync, if active. But somehow the ABP Framework tries to create the user again.
Volo.Abp.Account.Public.ExternalLoginUserProvider does not exist in the Account Pro module, where I could override CreateUserIfNotExistsAsync.
Currently I get the following error message if I have already created the user myself in TryAuthenticateAsync.
Stack Query Cookies Headers Routing AbpIdentityResultException: E-Mail ‚ldaptest2@abel-systems.ch‘ ist bereits vergeben. Microsoft.AspNetCore.Identity.AbpIdentityResultExtensions.CheckErrors(IdentityResult identityResult) Volo.Abp.Identity.ExternalLoginProviderBase.CreateUserAsync(ExternalLoginUserInfo externalUser, string userName, string providerName) Volo.Abp.Identity.ExternalLoginProviderBase. CreateUserAsync(string userName, string providerName) Volo.Abp.Identity.AspNetCore.AbpSignInManager.PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure) AbelSystems_QMP.Pages.Account.LoginModel.OnPostAsync(string action) in Login.cshtml.cs + var result = await SignInManager.PasswordSignInAsync(
Do you have any tips for me?
Uwe