在MVC 5中,我根据他们有权访问的控制器来控制菜单项(站点地图)的可见性。
我有一个模块管理页面,用于为每个控制器分配和取消分配权限。
我的AuthorizeAttribute看起来像这样:
public sealed class PermissionAttribute : AuthorizeAttribute {
public string Module { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext) {
if (!base.AuthorizeCore(httpContext)) {
return false;
}
var moduleManager = new ApplicationModuleManager();
var userId = httpContext.User.Identity.GetUserId();
return moduleManager.IsUserAccessibleModule(Convert.ToInt32(userId), Module);
}
public override void OnAuthorization(AuthorizationContext filterContext) {
base.OnAuthorization(filterContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
if (!filterContext.HttpContext.User.Identity.IsAuthenticated) {
base.HandleUnauthorizedRequest(filterContext);
return;
}
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "AccessDenied" },
{ "controller", "Error" },
{ "area", "" }
});
}
}
在控制器中:
[Permission(Module = "Admin")]
在MVC 6中,基于this问题和this doc,我需要编写授权要求。
public class ModuleAuthorizationHandler : AuthorizationHandler<ModuleRequirement> {
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ModuleRequirement requirement) {
if (!context.User.Identity.IsAuthenticated) {
return Task.CompletedTask;
}
//Do Module check
return Task.CompletedTask;
}
}
services.AddAuthorization(options => {
options.AddPolicy("Module", policy => policy.Requirements.Add(new ModuleRequirement()));
});
[Authorize(Policy = "Module")]
如何为每个控制器传递模块名称:[Permission(Module = "Admin")]
?或者有更好的方法吗?
注意:我是这样实现的,因为我的角色是动态的,可以重命名,删除,可以添加新角色,但模块是静态的。