Open Closed

Ldap Operations Error #2540


User avatar
0
mostafa_ibrahem22@hotmail.com created
  • ABP Framework version: v5.1.3
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

OS : Window 10

Operations Error. Operations Error. Result: 1. Method: ldap_parse_result. Details: ErrorMessage: 000004DC: LdapErr: DSID-0C090A71, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v3839


9 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    HI

    You should customize the built-in service.

    https://docs.abp.io/en/commercial/latest/modules/account/ldap#customize-built-in-services

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created

    Hi,

    I made these in the above images in a console application and customize LdapExternalLoginProvider on Identity Server, but the same error appear in both,

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    customize LdapExternalLoginProvider on Identity Server

    Can you share your code?

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created

    Hi

    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using LdapForNet;
    using LdapForNet.Native;
    
    namespace ConsoleApp1
    {
        internal class Program
        {
            static async Task Main(string[] args)
            {
                var server = "dc.mydc.com.ae";
                var serverPort = 389;
                var baseDc = "dc=mydc,dc=com,dc=ae";
                var adminUserName = "mydc\\testadminuser";
                var adminPassword = "testadminpassword";
                var testUserName = "testuser";
                var testPassword = "testuserpassword";
    
                using (var ldapConnection = new LdapConnection())
                {
                    ldapConnection.Connect(server, serverPort);
                    try
                    {
                        await ldapConnection.BindAsync(Native.LdapAuthType.Simple, new LdapCredential
                        {
                            // Configure username according to your LDAP config:
                            // cn=admin,dc=abp,dc=com or just username.
                            UserName = adminUserName,
                            Password = adminPassword
                        });
    
                        Console.WriteLine($"{adminUserName} login success!");
    
                        var searchResults = await ldapConnection.SearchAsync(baseDc, $"(&(objectClass=user)(sAMAccountName={testUserName}))");
    
                        Console.WriteLine();
                        Console.WriteLine($"{testUserName} attributes:");
    
                        var userEntry = searchResults.First();
                        Console.WriteLine(string.Join(", ", userEntry.ToDirectoryEntry().Attributes));
    
                        await ldapConnection.BindAsync(Native.LdapAuthType.Simple, new LdapCredential
                        {
                            UserName = userEntry.Dn,
                            Password = testPassword
                        });
    
                        Console.WriteLine();
                        Console.WriteLine($"{testUserName} login success!");
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                }
                Console.ReadKey();
    
            }
        }
    }
    

    same setting with different code working fine

    using (LdapConnection conn = new LdapConnection(new LdapDirectoryIdentifier(serverHost, serverPort)))
    {
        conn.Bind(new System.Net.NetworkCredential(userName, password, serverHost));
        return true;
    }
    
    using (PrincipalContext context = new PrincipalContext(ContextType.Domain, serverHost, userNameAuth, passwordAuth))
    using (UserPrincipal principal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, userName))
    {
        return principal.EmailAddress;
    }
                
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    customize LdapExternalLoginProvider on Identity Server

    Can you share the code that is customized? eg LdapExternalLoginProvider

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(OpenLdapManager), typeof(ILdapManager), typeof(LdapManager))]
    public class VoloOpenLdapManager : OpenLdapManager
    {
        public VoloOpenLdapManager(ILdapSettingProvider ldapSettingProvider)
            : base(ldapSettingProvider)
        {
    
        }
    
        protected override async Task<string> NormalizeUserNameAsync(string userName)
        {
            return Task.FromResult($"mydc\\{userName}");
        }
    
        protected override Task<string> GetUserFilterAsync(string userName)
        {
            return return Task.FromResult($"(&(objectClass=user)(sAMAccountName={userName}))");
        }
    
        protected override Task<string> GetUserEmailAsync(LdapEntry ldapEntry)
        {
            return Task.FromResult(ldapEntry.ToDirectoryEntry().GetAttribute("mail")?.GetValue<string>());
        }
    }
    
    
    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<string> NormalizeUserNameAsync(string userName)
        {
            // Default is $"uid={userName}, {BaseDc}"
            // or "userName@domain 
            // await LdapSettingProvider.GetDomainAsync()
            return Task.FromResult($"mydc\\{userName}");
        }
    }
    
    
    
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure<AbpIdentityOptions>(options =>
        {
            options.ExternalLoginProviders.Remove(LdapExternalLoginProvider.Name);
            options.ExternalLoginProviders.Add<VoloLdapExternalLoginProvider>(LdapExternalLoginProvider.Name);
        });
    }
    
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can I check this remotely? liming.ma@volosoft.com

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created

    hi,

    sorry maliming, because of this critical information,

    I Made new LdapExternalLoginProvider extened from ExternalLoginProviderBase, and remove old LdapExternalLoginProvider and register new code LdapExternalLoginProvider. and the code worked fine. if you can enhance code or resolve the problem, many thanks

    I used (System.DirectoryServices.AccountManagement)

    thanks maliming for your support.

    using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Volo.Abp.Account.Feature; using Volo.Abp.Account.Settings; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.Guids; using Volo.Abp.Identity; using Volo.Abp.Ldap; using Volo.Abp.MultiTenancy; using Volo.Abp.Settings; using Volo.Abp.Account.Public.Web.Ldap; using System.DirectoryServices.Protocols; using System.DirectoryServices.AccountManagement;

    namespace XXXX.Sso.Ldap { public class XXXXLdapExternalLoginProvider : ExternalLoginProviderBase, ITransientDependency { public const string Name = "Ldap";

        public ILogger&lt;LdapExternalLoginProvider&gt; Logger { get; set; }
    
        protected ILdapSettingProvider LdapSettingProvider { get; }
    
        protected IFeatureChecker FeatureChecker { get; }
    
        protected ISettingProvider SettingProvider { get; }
    
        public XXXXLdapExternalLoginProvider(IGuidGenerator guidGenerator,
            ICurrentTenant currentTenant,
            IdentityUserManager userManager,
            IIdentityUserRepository identityUserRepository,
            ILdapSettingProvider ldapSettingProvider,
            IFeatureChecker featureChecker,
            ISettingProvider settingProvider,
            IOptions&lt;IdentityOptions&gt; identityOptions)
                : base(guidGenerator,
                    currentTenant,
                    userManager,
                    identityUserRepository,
                    identityOptions)
        {
            LdapSettingProvider = ldapSettingProvider;
            FeatureChecker = featureChecker;
            SettingProvider = settingProvider;
    
            Logger = NullLogger&lt;LdapExternalLoginProvider&gt;.Instance;
        }
    
        public override async Task&lt;bool&gt; TryAuthenticateAsync(string userName, string plainPassword)
         {
            Logger.LogInformation("Try to use LDAP for external authentication");
    
            if (!await FeatureChecker.IsEnabledAsync(AccountFeature.EnableLdapLogin))
            {
                Logger.LogWarning("Ldap login feature is not enabled!");
                return false;
            }
    
            if (!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLdapLogin))
            {
                Logger.LogWarning("Ldap login setting is not enabled!");
                return false;
            }
    
            return await AuthenticateAsync(userName, plainPassword);
        }
    
        protected override async Task&lt;ExternalLoginUserInfo&gt; GetUserInfoAsync(string userName)
        {
            var email = await GetUserEmailAsync(userName);
            if (email.IsNullOrWhiteSpace())
            {
                throw new Exception("Unable to get the email of ldap user!");
            }
            return new ExternalLoginUserInfo(email);
        }
    
        private async Task&lt;bool&gt; AuthenticateAsync(string userName, string password)
        {
            string serverHost = await LdapSettingProvider.GetServerHostAsync();
            int serverPort = await LdapSettingProvider.GetServerPortAsync();
            string userNameAuth = await LdapSettingProvider.GetUserNameAsync();
            string passwordAuth = await LdapSettingProvider.GetPasswordAsync();
    
            try
            {
                using (LdapConnection conn = new LdapConnection(new LdapDirectoryIdentifier(serverHost, serverPort)))
                {
                    conn.Bind(new System.Net.NetworkCredential(userName, password, serverHost));
                    return true;
                }
            }
            catch (LdapException e)
            {
                Logger.LogException(e);
            }
    
            return false;
        }
    
        private async Task&lt;string&gt; GetUserEmailAsync(string userName)
        {
            string serverHost = await LdapSettingProvider.GetServerHostAsync();
            int serverPort = await LdapSettingProvider.GetServerPortAsync();
            string userNameAuth = await LdapSettingProvider.GetUserNameAsync();
            string passwordAuth = await LdapSettingProvider.GetPasswordAsync();
    
            try
            {
    

    #pragma warning disable CA1416 // Validate platform compatibility using (PrincipalContext context = new PrincipalContext(ContextType.Domain, serverHost, userNameAuth, passwordAuth)) using (UserPrincipal principal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, userName)) { return principal.EmailAddress; } #pragma warning restore CA1416 // Validate platform compatibility } catch (LdapException e) { Logger.LogException(e); }

            return string.Empty;
        }
    
    }
    

    }

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Good news.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 13, 2024, 06:09