You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net 6中Visus.LdapAuthentication如何配置多SearchBase做LDAP认证

解决Visus.LdapAuthentication多域LDAP认证问题

核心思路

由于你的两个SearchBase属于不同的LDAP域(DC=EEEEEEE,DC=com和DC=FFFFFFF,DC=com),无法通过单配置实现跨域搜索,最可靠的方式是分别注册两组独立的LDAP服务,再通过自定义门面服务统一处理认证和搜索逻辑。

步骤1:配置文件中添加两组LDAP配置

在appsettings.json中新增两个独立的LDAP配置节点,分别对应两个域:

{
  "LdapConfiguration1": {
    "Server": "ldap.eeeeeee.com",
    "Port": 389,
    "SearchBase": "OU=01-EEEEEEE,OU=Utilisateurs,DC=EEEEEEE,DC=com",
    "BindDn": "你的绑定账号DN",
    "BindPassword": "绑定账号密码",
    "SearchFilter": "(sAMAccountName={0})"
  },
  "LdapConfiguration2": {
    "Server": "ldap.fffffff.com",
    "Port": 389,
    "SearchBase": "OU=02-FFFFFFF,OU=Utilisateurs,DC=FFFFFFF,DC=com",
    "BindDn": "你的绑定账号DN",
    "BindPassword": "绑定账号密码",
    "SearchFilter": "(sAMAccountName={0})"
  }
}

步骤2:注册两组命名LDAP服务

在Program.cs中,分别注册两组LDAP认证和搜索服务,使用命名服务区分不同实例:

// 注册第一组LDAP服务
builder.Services.AddKeyedScoped<ILdapAuthenticationService, LdapAuthenticationService>("ldap-domain1", (sp, key) =>
{
    var opt = new LdapAuthenticationOptions();
    builder.Configuration.GetSection("LdapConfiguration1").Bind(opt);
    return new LdapAuthenticationService(opt, sp.GetRequiredService<ILogger<LdapAuthenticationService>>());
});
builder.Services.AddKeyedScoped<ILdapSearchService<LdapUser>, LdapSearchService<LdapUser>>("ldap-domain1", (sp, key) =>
{
    var opt = new LdapAuthenticationOptions();
    builder.Configuration.GetSection("LdapConfiguration1").Bind(opt);
    return new LdapSearchService<LdapUser>(opt, sp.GetRequiredService<ILogger<LdapSearchService<LdapUser>>>());
});

// 注册第二组LDAP服务
builder.Services.AddKeyedScoped<ILdapAuthenticationService, LdapAuthenticationService>("ldap-domain2", (sp, key) =>
{
    var opt = new LdapAuthenticationOptions();
    builder.Configuration.GetSection("LdapConfiguration2").Bind(opt);
    return new LdapAuthenticationService(opt, sp.GetRequiredService<ILogger<LdapAuthenticationService>>());
});
builder.Services.AddKeyedScoped<ILdapSearchService<LdapUser>, LdapSearchService<LdapUser>>("ldap-domain2", (sp, key) =>
{
    var opt = new LdapAuthenticationOptions();
    builder.Configuration.GetSection("LdapConfiguration2").Bind(opt);
    return new LdapSearchService<LdapUser>(opt, sp.GetRequiredService<ILogger<LdapSearchService<LdapUser>>>());
});

步骤3:实现多域认证门面服务

创建一个自定义服务,整合两组LDAP认证逻辑,依次尝试两个域的认证:

public class MultiDomainLdapAuthenticationService : ILdapAuthenticationService
{
    private readonly ILdapAuthenticationService _domain1AuthService;
    private readonly ILdapAuthenticationService _domain2AuthService;

    public MultiDomainLdapAuthenticationService(
        [FromKeyedServices("ldap-domain1")] ILdapAuthenticationService domain1AuthService,
        [FromKeyedServices("ldap-domain2")] ILdapAuthenticationService domain2AuthService)
    {
        _domain1AuthService = domain1AuthService;
        _domain2AuthService = domain2AuthService;
    }

    public async Task<bool> AuthenticateAsync(string username, string password, CancellationToken cancellationToken = default)
    {
        // 先尝试第一个域
        try
        {
            if (await _domain1AuthService.AuthenticateAsync(username, password, cancellationToken))
                return true;
        }
        catch (Exception)
        {
            // 忽略单个域的连接/认证异常,继续尝试第二个域
        }

        // 再尝试第二个域
        try
        {
            return await _domain2AuthService.AuthenticateAsync(username, password, cancellationToken);
        }
        catch (Exception)
        {
            return false;
        }
    }
}

步骤4:实现多域搜索门面服务

同理,创建搜索服务的门面类,整合两个域的用户搜索:

public class MultiDomainLdapSearchService : ILdapSearchService<LdapUser>
{
    private readonly ILdapSearchService<LdapUser> _domain1SearchService;
    private readonly ILdapSearchService<LdapUser> _domain2SearchService;

    public MultiDomainLdapSearchService(
        [FromKeyedServices("ldap-domain1")] ILdapSearchService<LdapUser> domain1SearchService,
        [FromKeyedServices("ldap-domain2")] ILdapSearchService<LdapUser> domain2SearchService)
    {
        _domain1SearchService = domain1SearchService;
        _domain2SearchService = domain2SearchService;
    }

    public async Task<LdapUser?> SearchUserAsync(string username, CancellationToken cancellationToken = default)
    {
        var user = await _domain1SearchService.SearchUserAsync(username, cancellationToken);
        if (user != null)
            return user;
        
        return await _domain2SearchService.SearchUserAsync(username, cancellationToken);
    }

    // 若接口有其他方法,按相同逻辑实现即可
}

步骤5:注册门面服务

最后将自定义的门面服务注册到DI容器,覆盖原始接口的默认实现:

builder.Services.AddScoped<ILdapAuthenticationService, MultiDomainLdapAuthenticationService>();
builder.Services.AddScoped<ILdapSearchService<LdapUser>, MultiDomainLdapSearchService>();

替代方案(仅适用于域间有信任关系)

如果两个域之间已建立信任,且绑定账号拥有全局搜索权限,可以尝试使用全局编录(端口3268)进行跨域搜索:

  1. 将LDAP服务器地址改为全局编录地址,端口设为3268
  2. SearchBase设为空字符串或根域(如DC=com)
  3. 修改SearchFilter为包含两个OU的OR条件:
(&(objectClass=user)(|(distinguishedName=*,OU=01-EEEEEEE,OU=Utilisateurs,DC=EEEEEEE,DC=com)(distinguishedName=*,OU=02-FFFFFFF,OU=Utilisateurs,DC=FFFFFFF,DC=com)))

但此方案依赖域信任和高权限账号,稳定性不如独立配置方案。


内容的提问来源于stack exchange,提问作者Kamil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:00:57