ASP.NET Core MVC中如何实现指定用户/角色的Windows身份认证及权限管控?
Windows身份认证内网应用的自定义用户权限验证方案
一、自定义用户列表验证的实现步骤
1. 启用Windows身份认证
对于ASP.NET Core项目,在Program.cs中配置认证服务:
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme); builder.Services.AddAuthorization();
如果是ASP.NET Framework项目,在web.config中启用Windows认证节点:
<system.web> <authentication mode="Windows" /> </system.web>
2. 创建允许访问的用户数据库表
新建一张AllowedUsers表,核心字段为DomainUsername(存储格式为DOMAIN\用户名,和Windows认证返回的用户名格式一致),可按需添加备注、创建时间等字段。
3. 实现自定义验证逻辑
有两种常用方式:
方式一:自定义授权策略(推荐用于局部验证)
创建授权需求和处理类:
// 定义授权需求 public class AllowedUserRequirement : IAuthorizationRequirement { } // 实现授权处理逻辑 public class AllowedUserHandler : AuthorizationHandler<AllowedUserRequirement> { private readonly IAllowedUserRepository _userRepo; public AllowedUserHandler(IAllowedUserRepository userRepo) { _userRepo = userRepo; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, AllowedUserRequirement requirement) { var domainUsername = context.User.Identity?.Name; if (string.IsNullOrEmpty(domainUsername)) { context.Fail(); return; } // 查询数据库判断用户是否在允许列表中 bool isAllowed = await _userRepo.CheckUserExistsAsync(domainUsername); if (isAllowed) { context.Succeed(requirement); } else { context.Fail(); } } }
然后在Program.cs注册服务并添加授权策略:
// 注册数据库访问仓储 builder.Services.AddScoped<IAllowedUserRepository, AllowedUserRepository>(); // 添加授权策略 builder.Services.AddAuthorization(options => { options.AddPolicy("AllowedUserOnly", policy => policy.Requirements.Add(new AllowedUserRequirement())); }); // 注册授权处理类 builder.Services.AddScoped<IAuthorizationHandler, AllowedUserHandler>();
最后在需要验证的控制器或页面上添加特性:
[Authorize(Policy = "AllowedUserOnly")] public class HomeController : Controller { // 控制器逻辑 }
方式二:全局中间件(用于全站点验证)
编写中间件处理全局验证和重定向:
public class AllowedUserMiddleware { private readonly RequestDelegate _next; private readonly IAllowedUserRepository _userRepo; public AllowedUserMiddleware(RequestDelegate next, IAllowedUserRepository userRepo) { _next = next; _userRepo = userRepo; } public async Task InvokeAsync(HttpContext context) { var domainUsername = context.User.Identity?.Name; if (!string.IsNullOrEmpty(domainUsername)) { bool isAllowed = await _userRepo.CheckUserExistsAsync(domainUsername); if (!isAllowed) { // 重定向到无权限静态页面 context.Response.Redirect("/unauthorized.html"); return; } } await _next(context); } }
在Program.cs中注册中间件(注意顺序要在UseAuthentication和UseAuthorization之后):
app.UseAuthentication(); app.UseAuthorization(); // 注册自定义中间件 app.UseMiddleware<AllowedUserMiddleware>();
4. 配置无权限提示页面
在wwwroot目录下创建unauthorized.html,编写提示内容:
<!DOCTYPE html> <html> <head> <title>无访问权限</title> </head> <body> <h1>抱歉,您没有访问该应用的权限</h1> <p>请联系管理员申请访问权限</p> </body> </html>
二、ASP.NET Identity在Windows身份认证下的权限解决方案
ASP.NET Identity可以和Windows身份认证结合使用,解决权限问题,具体如下:
1. 配置Identity与Windows认证集成
在Program.cs中同时配置Windows认证和Identity:
// 配置数据库上下文 builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // 添加Identity服务 builder.Services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>(); // 配置认证方案,优先使用Windows认证 builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme; options.DefaultChallengeScheme = IISDefaults.AuthenticationScheme; }).AddWindows();
2. 同步域用户到Identity表
Windows认证返回的用户名是DOMAIN\用户名,需要将允许访问的域用户同步到Identity的AspNetUsers表中:
- 可手动导入允许的用户,设置
UserName字段为DOMAIN\用户名; - 也可在用户首次登录时自动创建用户(需判断是否在允许列表中,不在则拒绝)。
3. 使用[Authorize]特性及角色权限
- 验证用户存在:直接在控制器或页面添加
[Authorize]特性,只有Identity表中存在的域用户才能访问; - 角色权限控制:给Identity用户分配角色后,使用
[Authorize(Roles = "Admin,Operator")],只有属于指定角色的域用户才能访问对应资源。
4. 优缺点对比
- 优点:复用Identity成熟的用户、角色管理体系,无需从零编写验证逻辑;
- 缺点:需要维护Identity用户表,额外处理域用户与Identity用户的同步问题。
内容的提问来源于stack exchange,提问作者Dreidel
相关产品推荐
相关产品推荐

