ASP.NET MVC5迁移.NET 5 Core MVC 实现基于用户Locked属性的控制器授权
ASP.NET MVC5自定义授权迁移至ASP.NET Core 5方案
完全可以实现完全一致的授权逻辑,ASP.NET Core中推荐使用以下两种方案实现:
方案1:自定义IAuthorizationFilter(快速迁移首选)
该方案改造成本极低,用法和原有CustomAuthorizeAttribute完全一致。
步骤1:实现授权过滤器
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Identity; using YourNamespace.Models; // 替换为你项目中ApplicationUser的实际命名空间 public class CustomAuthorizeFilter : IAuthorizationFilter { private readonly UserManager<ApplicationUser> _userManager; private readonly string _roles; private readonly string _policy; public CustomAuthorizeFilter(UserManager<ApplicationUser> userManager, string roles, string policy) { _userManager = userManager; _roles = roles; _policy = policy; } public void OnAuthorization(AuthorizationFilterContext context) { // 跳过标注[AllowAnonymous]的接口/控制器 var hasAllowAnonymous = context.ActionDescriptor.EndpointMetadata .Any(m => m is AllowAnonymousAttribute); if (hasAllowAnonymous) return; var currentUser = context.HttpContext.User; // 未登录/用户名为空走默认授权逻辑 if (currentUser.Identity == null || !currentUser.Identity.IsAuthenticated || string.IsNullOrEmpty(currentUser.Identity.Name)) { context.Result = new ChallengeResult(); return; } // 获取当前登录的ApplicationUser实体 var applicationUser = _userManager.GetUserAsync(currentUser).GetAwaiter().GetResult(); if (applicationUser == null) { context.Result = new ChallengeResult(); return; } // 用户锁定直接跳转到未授权页 if (applicationUser.IsLocked) { context.Result = new RedirectResult("~/home/unauthorized"); return; } // 校验角色/策略权限 var authorizeBuilder = new AuthorizationPolicyBuilder(); if (!string.IsNullOrEmpty(_roles)) authorizeBuilder.RequireRole(_roles.Split(',')); if (!string.IsNullOrEmpty(_policy)) authorizeBuilder.RequirePolicy(_policy); var policy = authorizeBuilder.Build(); var authResult = context.HttpContext.AuthenticateAsync().GetAwaiter().GetResult(); var authorizeResult = new DefaultAuthorizationService( new[] { new DefaultAuthorizationHandlerProvider(new IAuthorizationHandler[] { }) }, new DefaultAuthorizationPolicyProvider(Microsoft.Extensions.Options.Options.Create(new AuthorizationOptions())), new DefaultAuthorizationHandlerContextFactory(), new DefaultAuthorizationEvaluator(), Microsoft.Extensions.Options.Options.Create(new AuthorizationOptions()) ).AuthorizeAsync(authResult.Principal, context.Resource, policy).GetAwaiter().GetResult(); if (!authorizeResult.Succeeded) { context.Result = new RedirectResult("~/home/unauthorized"); } } }
步骤2:实现对应的自定义Attribute
public class CustomAuthorizeAttribute : TypeFilterAttribute { /// <summary> /// 允许访问的角色,多个用英文逗号分隔 /// </summary> public string Roles { get; set; } /// <summary> /// 授权策略名称 /// </summary> public string Policy { get; set; } public CustomAuthorizeAttribute() : base(typeof(CustomAuthorizeFilter)) { Arguments = new object[] { Roles, Policy }; } }
步骤3:注册服务
在Startup.cs的ConfigureServices方法中添加过滤器注册:
services.AddScoped<CustomAuthorizeFilter>();
使用方式
和原有用法完全一致,直接在控制器或者Action上标注即可:
[CustomAuthorize(Roles = "Admin")] public class AdminController : Controller { // ... }
方案2:基于策略的授权(官方推荐,扩展性更强)
符合ASP.NET Core的原生设计规范,适合后续授权逻辑需要扩展的场景。
步骤1:定义授权需求
using Microsoft.AspNetCore.Authorization; public class ValidUserRequirement : IAuthorizationRequirement { }
步骤2:实现需求处理器
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using YourNamespace.Models; public class ValidUserHandler : AuthorizationHandler<ValidUserRequirement> { private readonly UserManager<ApplicationUser> _userManager; public ValidUserHandler(UserManager<ApplicationUser> userManager) { _userManager = userManager; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidUserRequirement requirement) { if (context.User.Identity == null || !context.User.Identity.IsAuthenticated) { context.Fail(); return; } var user = await _userManager.GetUserAsync(context.User); if (user == null || user.IsLocked) { context.Fail(); return; } context.Succeed(requirement); } }
步骤3:注册授权策略和处理器
在Startup.cs的ConfigureServices方法中添加注册:
services.AddAuthorization(options => { options.AddPolicy("ValidUser", policy => { policy.RequireAuthenticatedUser(); policy.AddRequirements(new ValidUserRequirement()); // 可在此添加其他授权要求,如RequireRole("Admin")等 }); }); services.AddScoped<IAuthorizationHandler, ValidUserHandler>(); // 配置未授权跳转路径 services.ConfigureApplicationCookie(options => { options.AccessDeniedPath = "/home/unauthorized"; });
使用方式
在需要授权的控制器或Action上标注即可:
[Authorize(Policy = "ValidUser", Roles = "Admin")] public class AdminController : Controller { // ... }
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

