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

ASP.NET Core MVC 3.1能否沿用MVC5的MembershipProvider LDAP认证方案?

问题描述

我们现有一个ASP.NET MVC 5 Web应用,通过以下代码实现基于LDAP的用户认证:

[HttpPost]
[AllowAnonymous]
[ValidateInput(false)]
public ActionResult Login(LoginModel model, string returnUrl)
{
    MembershipProvider domainProvider;
    domainProvider = Membership.Providers["TestDomain1ADMembershipProvider"];
    if (ModelState.IsValid)
    {
        // 用会员系统验证用户
        if (domainProvider.ValidateUser(model.UserName, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
            RedirectToAction("Index","Home");
        }
        else
        {
            ModelState.AddModelError("", "提供的用户名或密码不正确。");
            return View(model);
        }
    }
    return View(model);
}

对应的web.config配置如下:

<membership>
  <providers>
    <add name="TestDomain1ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="TestDomain1ConnectionString" connectionUsername="Administrator" connectionPassword="*****" attributeMapUsername="sAMAccountName"/>
  </providers>
</membership>

<connectionStrings>
  <add name="TestDomain1ConnectionString" connectionString="LDAP://mydomain.com/CN=Users,DC=mydomain,DC=com"/>
</connectionStrings>

现咨询:将应用从ASP.NET MVC 5升级至ASP.NET Core MVC 3.1后,能否沿用该认证方案?若不可行,应采用何种方式实现LDAP用户认证?


回答

能否沿用原有认证方案?

不能直接沿用。ASP.NET Core完全重构了认证体系,不再支持System.Web.Security.ActiveDirectoryMembershipProvider、FormsAuthentication这类传统ASP.NET专属API,web.config中的<membership>配置也不会被ASP.NET Core读取。

ASP.NET Core MVC 3.1中实现LDAP认证的方案

方案1:用第三方库手动实现LDAP验证(通用方案)

最常用的方式是借助Novell.Directory.Ldap.NETStandard库直接操作LDAP协议完成用户验证:

  1. 安装NuGet包:Novell.Directory.Ldap.NETStandard
  2. 编写LDAP验证服务:
using Novell.Directory.Ldap;

public class LdapAuthService
{
    private readonly string _ldapServer;
    private readonly int _ldapPort;
    private readonly string _baseDn;

    public LdapAuthService(string ldapServer, int ldapPort, string baseDn)
    {
        _ldapServer = ldapServer;
        _ldapPort = ldapPort;
        _baseDn = baseDn;
    }

    public bool ValidateCredentials(string username, string password)
    {
        if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
            return false;

        try
        {
            using var connection = new LdapConnection();
            // 连接LDAP服务器
            connection.Connect(_ldapServer, _ldapPort);
            // 用用户账号密码绑定验证
            connection.Bind($"CN={username},{_baseDn}", password);
            
            // 绑定成功则验证通过
            return connection.Bound;
        }
        catch (LdapException)
        {
            // 用户名错误、密码错误或用户不存在都会触发异常,直接返回验证失败
            return false;
        }
    }
}
  1. 在Startup.cs中配置服务和Cookie认证:
using Microsoft.AspNetCore.Authentication.Cookies;

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    
    // 注册LDAP认证服务,从配置文件读取参数
    services.AddSingleton<LdapAuthService>(provider =>
    {
        var config = provider.GetRequiredService<IConfiguration>();
        return new LdapAuthService(
            config["Ldap:Server"],
            int.Parse(config["Ldap:Port"]),
            config["Ldap:BaseDn"]
        );
    });
    
    // 配置Cookie认证(替代原FormsAuthentication)
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.LoginPath = "/Account/Login";
            options.ExpireTimeSpan = TimeSpan.FromDays(7);
        });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 其他中间件(如异常处理、静态文件)...
    
    // 启用认证和授权中间件
    app.UseAuthentication();
    app.UseAuthorization();
    
    // 路由中间件...
}
  1. 修改Login Action逻辑:
private readonly LdapAuthService _ldapAuth;

public AccountController(LdapAuthService ldapAuth)
{
    _ldapAuth = ldapAuth;
}

[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginModel model, string returnUrl)
{
    if (!ModelState.IsValid)
        return View(model);

    if (_ldapAuth.ValidateCredentials(model.UserName, model.Password))
    {
        // 创建认证票据
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, model.UserName)
        };
        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        var principal = new ClaimsPrincipal(identity);
        
        // 登录并生成Cookie
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties
        {
            IsPersistent = model.RememberMe
        });
        
        return LocalRedirect(returnUrl ?? Url.Action("Index", "Home"));
    }
    
    ModelState.AddModelError("", "提供的用户名或密码不正确。");
    return View(model);
}
  1. 在appsettings.json中添加LDAP配置:
{
  "Ldap": {
    "Server": "mydomain.com",
    "Port": 389,
    "BaseDn": "CN=Users,DC=mydomain,DC=com"
  }
}

方案2:Windows集成认证(域环境专属)

如果应用部署在已加入域的服务器上,且用户通过域账号访问内部系统,可直接启用Windows认证,无需手动编写验证逻辑:

  1. 在Startup.cs中配置:
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddAuthentication(IISDefaults.AuthenticationScheme);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 其他中间件...
    app.UseAuthentication();
    app.UseAuthorization();
    // 路由中间件...
}
  1. 在launchSettings.json中开启Windows认证:
{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false
  }
}

这种方式下用户无需手动输入账号密码,会自动通过域身份完成登录,适合企业内部系统。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:51:03