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

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11