Open Closed

AD integration using LDAP #5858


User avatar
0
s.alshammari.c created

Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, and please first use the search on the homepage. Provide us with the following info:

  • ABP Framework version: v7.3.0
  • UI Type: Angular / MVC
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): No
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

I am trying to integrate my Angular Application (Created using ABP Suite) with my enterprise Active Directory as an Authentication mechanism using LDAP UI . However, I keep getting "Invalid Username/Password"


19 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    We have an example to help you to check LDAP settings:

    https://github.com/abpframework/abp-samples/tree/master/AbpLdapSample

  • User Avatar
    0
    s.alshammari.c created

    I tried AbpLdapSample and its working. However, I still have issue with my App as I mentioned earlier

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Could you share the application logs? thanks.

  • User Avatar
    0
    s.alshammari.c created

    this is the log

    [10:13:48 INF] Executing endpoint '/Account/Login' [10:13:48 INF] Route matched with {page = "/Account/Login", action = "", controller = "", area = ""}. Executing page /Account/Login [10:13:48 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy [10:13:48 INF] Executing handler method Volo.Abp.Account.Public.Web.Pages.Account.LoginModel.OnPostAsync - ModelState is Valid [10:13:48 INF] Try to use LDAP for external authentication [10:13:48 ERR] Invalid Credentials. Invalid Credentials. Result: 49. Method: ldap_parse_result. Details: errorMessage: 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563 matchedMessage: LdapForNet.LdapInvalidCredentialsException: Invalid Credentials. Invalid Credentials. Result: 49. Method: ldap_parse_result. Details: errorMessage: 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563 matchedMessage:  at LdapForNet.Native.LdapNative.ThrowIfError(SafeHandle ld, Int32 res, String method, IDictionary`2 details)  at LdapForNet.LdapConnection.ThrowIfParseResultError(IntPtr msg)  at LdapForNet.LdapConnection.BindAsync(LdapAuthType authType, LdapCredential ldapCredential)  at Volo.Abp.Ldap.LdapManager.AuthenticateLdapConnectionAsync(ILdapConnection connection, String username, String password)  at Volo.Abp.Ldap.LdapManager.AuthenticateAsync(String username, String password)

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    I will check it

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    It works for me:

    LDAP server:

    docker run --name ldap -d --env LDAP_ORGANISATION="abp" --env LDAP_DOMAIN="abp.com" --env LDAP_ADMIN_PASSWORD="123456" -p 389:389 -p 636:639 --detach osixia/openldap

    LDAP user:

  • User Avatar
    0
    s.alshammari.c created

    I followed what you did and it works fine. I noticed that you are using

    filter="(&(uid=testuser))

    I don't have uid in my AD

    instead of using uid i would like to use sAMAccountName because I used it in the AbpLDAPSample

    and it worked

    so

    how can I change filter="(&(uid=testuser)) to (&(objectClass=user)(sAMAccountName={testuser})

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can check the document: https://docs.abp.io/en/commercial/latest/modules/identity/ldap#customize-built-in-services

  • User Avatar
    0
    s.alshammari.c created

    I managed to integrate the AD and my App successfully but now I get this Exception when i try to login

    Exception: Unable to get the email of ldap user!

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    You need to add the mail attribute to the LDAP user.

    Or you can override the GetUserEmailAsync method

  • User Avatar
    0
    s.alshammari.c created

    I have the mail attribute in AD and also the same code you sent and I still have this issue Exception: Unable to get the email of ldap user!

    when I import user like this

    it work

    but when I try to login from login page I get this exception

    Exception: Unable to get the email of ldap user!

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    I think it returns a null value.

    This is the source code:

    protected async override Task<ExternalLoginUserInfo> GetUserInfoAsync(string userName)
    {
        var email = await LdapManager.GetUserEmailAsync(userName);
        if (email.IsNullOrWhiteSpace())
        {
            throw new Exception("Unable to get the email of ldap user!");
        }
        return new ExternalLoginUserInfo(email);
    }
    
    -------------
    
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(OpenLdapManager), typeof(ILdapManager), typeof(LdapManager))]
    public class OpenLdapManager : LdapManager
    {
        public OpenLdapManager(ILdapSettingProvider ldapSettingProvider)
            : base(ldapSettingProvider)
        {
    
        }
    
        public virtual async Task<string> GetUserEmailAsync(string userName)
        {
            using (var conn = await CreateLdapConnectionAsync())
            {
                await AuthenticateLdapConnectionAsync(conn, await NormalizeUserNameAsync(await LdapSettingProvider.GetUserNameAsync()), await LdapSettingProvider.GetPasswordAsync());
    
                var searchResults = await conn.SearchAsync(await GetBaseDnAsync(), await GetUserFilterAsync(userName));
                try
                {
                    var userEntry = searchResults.First();
                    return await GetUserEmailAsync(userEntry);
                }
                catch (LdapException e)
                {
                    Logger.LogException(e);
                }
    
                return null;
            }
        }
    
        protected async override Task ConnectAsync(ILdapConnection ldapConnection)
        {
            ldapConnection.Connect(await LdapSettingProvider.GetServerHostAsync(), await LdapSettingProvider.GetServerPortAsync());
        }
    
        protected virtual async Task<string> NormalizeUserNameAsync(string userName)
        {
            return $"cn={userName},{await LdapSettingProvider.GetBaseDcAsync()}";
        }
    
        protected virtual Task<string> GetUserEmailAsync(LdapEntry ldapEntry)
        {
            return Task.FromResult(ldapEntry.ToDirectoryEntry().GetAttribute("mail")?.GetValue<string>());
        }
    
        protected virtual async Task<string> GetBaseDnAsync()
        {
            return await LdapSettingProvider.GetBaseDcAsync();
        }
    
        protected virtual Task<string> GetUserFilterAsync(string userName)
        {
            return Task.FromResult($"(&(uid={userName}))");
        }
    }
    
  • User Avatar
    0
    s.alshammari.c created

    ok Good

    now once I login with right credentials

    I get this.

    keep in mind this is only happening on login page and not when importing users

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Because it didn't find a user!

    The search code logic is the same as the AbpLdapSample example:

    https://github.com/abpframework/abp-samples/blob/master/AbpLdapSample/AbpLdapSample/Program.cs#L38

    You can test your LDAP configuration through AbpLdapSample.

    If it still doesn't work, can you share the LDAP configuration and test users with me? shiwei.liang@volosoft.com I'll check it.

  • User Avatar
    0
    s.alshammari.c created

    its working on AbpLdapSamle

    in my app some users successfully logged and some other users trigger the error above, they all have same attribute i don't know why some users can login and others cannot.

    this user logged in successfully

    this user cannot login and i get invalid username/password in login page

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    How I reproduce the problem. could you share the full steps to reproduce? I will check it. thanks.

  • User Avatar
    0
    s.alshammari.c created

    here is my code

    using Microsoft.AspNetCore.Identity; using System.Threading.Tasks; using Volo.Abp.Features; using Volo.Abp.Guids; using Volo.Abp.Identity.ExternalLoginProviders.Ldap; using Volo.Abp.Identity; using Volo.Abp.Ldap; using Volo.Abp.MultiTenancy; using Volo.Abp.Settings; using Microsoft.Extensions.Options; using LdapForNet;

    namespace TestApp.Web { public class VoloLdapExternalLoginProvider : LdapExternalLoginProvider { public VoloLdapExternalLoginProvider( IGuidGenerator guidGenerator, ICurrentTenant currentTenant, IdentityUserManager userManager, IIdentityUserRepository identityUserRepository, OpenLdapManager ldapManager, ILdapSettingProvider ldapSettingProvider, IFeatureChecker featureChecker, ISettingProvider settingProvider, IOptions<IdentityOptions> identityOptions) : base(guidGenerator, currentTenant, userManager, identityUserRepository, ldapManager, ldapSettingProvider, featureChecker, settingProvider, identityOptions) {

        }
    
        protected override async Task&lt;string&gt; NormalizeUserNameAsync(string userName)
        {
            // Default is $"uid={userName}, {BaseDc}"
            // or "userName@domain 
            //await LdapSettingProvider.GetDomainAsync();
          var loginUserName= await Task.FromResult($"{userName}");
            return loginUserName;
        }
    
    
    
        
    }
    

    }


    using LdapForNet; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Identity.ExternalLoginProviders.Ldap; using Volo.Abp.Ldap;

    namespace TestApp.Web { [Dependency(ReplaceServices = true)] [ExposeServices(typeof(OpenLdapManager), typeof(ILdapManager), typeof(LdapManager))] public class VoloOpenLdapManager : OpenLdapManager { public VoloOpenLdapManager(ILdapSettingProvider ldapSettingProvider) : base(ldapSettingProvider) {

        }
    
        protected override async Task&lt;string&gt; NormalizeUserNameAsync(string userName)
        {
            // or "userName@domain 
            //await LdapSettingProvider.GetDomainAsync();
            return await Task.FromResult($"{userName}");
        }
    
        protected override Task&lt;string&gt; GetUserFilterAsync(string userName)
        {
            // Default is $"cn={userName},{LdapOptions.BaseDc}"
            return Task.FromResult($"(&(objectClass=user)(sAMAccountName={userName}))");
            
        }
    
        protected override Task&lt;string&gt; GetUserEmailAsync(LdapEntry ldapEntry)
        {
            return Task.FromResult(ldapEntry.ToDirectoryEntry().GetAttribute("mail")?.GetValue&lt;string&gt;());
            
        }
    }
    

    }

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Please share the full steps include the LDAP server Information(users etc..)

  • User Avatar
    0
    s.alshammari.c created

    I solved the issue

    problem was on class VoloLdapExternalLoginProvider

    before

    after

    I had to add the domain here

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on July 14, 2025, 11:57