自定义授权(权限)ASP.NET MVC
在我的应用程序中,角色具有多个权限。 我希望用户能够访问依赖于权限的操作,而不是角色。
所以假设:
我想做以下事情:我想让那些假设perm3或perm4的人可以访问。 这两个权限来自两个不同的角色。 但是除了perm3 Admin有perm1和perm2之外,这个动作也可以由具有perm3的小家伙访问(不一定是admin或superadmin)。
所以你明白我的意思吧? 我想在ASP.NET MVC 4中实现这一点。所以我想我需要创建自己的AuthorizeAttribute
,我自己的IIdentity
并在global.asax中编写一些方法。 ASP.NET中还有一个成员资格我是否需要触摸它? 我不知道如何把所有的东西放在一起。 谁能帮我吗?
public class PermissionAttribute : AuthorizeAttribute { private readonly IAccountService _accountService; private readonly IEnumerable _permissions; public PermissionAttribute(params PermissionEnum[] permissions): this(DependencyResolver.Current.GetService()) { _permissions = permissions; } protected PermissionAttribute(IAccountService accountService) { _accountService = accountService; } public override void OnAuthorization(AuthorizationContext filterContext) { if(!_permissions.Any(x=>_accountService.HasPermission(filterContext.HttpContext.User.Identity.Name,(int)x))) filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden); base.OnAuthorization(filterContext); } }
基本上你必须创建自己的AuthorizeAttribute,但是使用.NET中的IIdentity。 您在此处描述的是基于声明的身份validation和授权系统。
很可能您将不得不从ASP.NET中丢弃成员资格或仅使用其中的一部分。 据我所知,它并没有考虑到索赔。
在.NET 4.5中,这些人添加了类:ClaimsPrincipal,它实现了IPrincipal接口。 此类可用于实现基于声明的自定义身份validation和授权。
因此,当用户通过身份validation时,您可以在线程上添加声明:
var id = new ClaimsIdentity(claims, "Dummy"); var principal = new ClaimsPrincipal(new[] { id }); Thread.CurrentPrincipal = principal;
然后再使用你在Thread.CurrentPrincipal上找到的声明。
在ASP.NET MVC中,您可以执行以下步骤:
-
创建一个委托处理程序,用于对用户进行身份validation。 如果用户已通过身份validation,则会将声明添加到线程主体。 理想情况下,此委托处理程序应尽可能高,以便您可以在执行链中的任何位置使用声明。 还记得使用相同的主体设置HttpContext.Current.User
公共类AuthHandler:DelegatingHandler {
protected override async Task
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { //authenticate user //get claims //create principal var newPrincipal = CreatePrincipal(claims); Thread.CurrentPrincipal = newPrincipal; if (HttpContext.Current != null) HttpContext.Current.User = newPrincipal; return await base.SendAsync(request, cancellationToken); } }
-
创建一个filter,根据添加到Thread Principal的声明进行授权。 在这里,您可以执行诸如将当前路线与声明中的信息进行比较之类的操作。
所以我认为你说的是:只有当用户有perm1,perm2时才能访问ActionA,并且当用户有perm1和perm3时,类似的ActionB是可访问的
我给出的代码是为了说明,我没有编译它。 但是会给你我所说的方法的图片
步骤1:您可以继续创建使用Flags属性归属的权限枚举
第2步:根据存储在数据存储中的用户权限向当前主体添加声明。
第3步:调用Action时,授权访问声明
[Flags] enum PermType { None = 0x0, Perm1 = 0x1, perm2 = 0x2, perm3 = 0x4, perm4 = 0x8, perm5 = 0x10 }
将声明添加到CurrentPrincipal
var currentPrincipal = ClaimsPrincipal.Current; var cms = currentPrincipal.Claims; var permissions = PermType.Perm1 | PermType.perm2; var claims = cms.ToList(); claims.Add(new Claim("Action1", permissions.ToString())); claims.Add(new Claim("Action2", permissions.ToString())); claims.Add(new Claim("Action3", permissions.ToString())); System.Threading.Thread.CurrentPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims));
检查用户是否可以访问特定操作
public bool CanAccessThisAction(string acionName,PermType requiredPerms) { var claim = principal.Claims.FirstOrDefault(c => c.Type == acionName); if (customPermissionClaim != null) { //check if required permission is present in claims for this user //return true/false } return false; }
在行动
上述就是C#学习教程:自定义授权(权限)ASP.NET MVC分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public ActionResult TestAction(string id) { if(CanAccessThisAction("TestAction",PermType.Perm1|PermType.perm3|PermType.perm5)) { //do your work here } else { //redirect user to some other page which says user is not authorized } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1023778.html