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协议完成用户验证:
- 安装NuGet包:
Novell.Directory.Ldap.NETStandard - 编写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; } } }
- 在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(); // 路由中间件... }
- 修改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); }
- 在appsettings.json中添加LDAP配置:
{ "Ldap": { "Server": "mydomain.com", "Port": 389, "BaseDn": "CN=Users,DC=mydomain,DC=com" } }
方案2:Windows集成认证(域环境专属)
如果应用部署在已加入域的服务器上,且用户通过域账号访问内部系统,可直接启用Windows认证,无需手动编写验证逻辑:
- 在Startup.cs中配置:
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddAuthentication(IISDefaults.AuthenticationScheme); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件... app.UseAuthentication(); app.UseAuthorization(); // 路由中间件... }
- 在launchSettings.json中开启Windows认证:
{ "iisSettings": { "windowsAuthentication": true, "anonymousAuthentication": false } }
这种方式下用户无需手动输入账号密码,会自动通过域身份完成登录,适合企业内部系统。
内容的提问来源于stack exchange,提问作者John John
相关产品推荐
相关产品推荐

