基于权限的授权.net标识

时间:2014-11-20 19:35:03

标签: .net asp.net-mvc asp.net-identity user-permissions

我是.NET,MVC&身份框架。我注意到身份框架允许通过注释保护单个控制器操作。

[Authorize]
public ActionResult Edit(int? Id){
    //edit action
}

我想基于用户权限保护某些操作。

示例:一个博客应用程序,只有创建博客文章的用户才能编辑。

考虑到这一点,是否可以执行以下任一选项?如果是这样,是否有关于如何最好地实现的资源和示例?

[Authorize(Entity = "Entry", Permission = "Edit", Id = Id)]
public ActionResult Edit(int? Id){
    //edit action
}

[BlogEntryPermission(Permission = "Edit", Id = Id)]
public ActionResult Edit(int? Id){
    //edit action
}

从请求中捕获博客Id的位置。

基于权限的身份验证的任何信息或指示都将非常受欢迎。在此先感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

您可以实施自定义AuthorizationAttribute,您可以在其中指定参数,并可以从请求中获取blogId

public class AuthorizeEntryPermission : AuthorizeAttribute
{
        public string Permission { get; set; }

        public AuthorizeEntryPermission(){
        }

        public AuthorizeEntryPermission(string Permission)
        {
            this.Permission = Permission;
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
             var id = context.Request.RequestContext.RouteData.Values["Id"];
             //check your permissions
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (AuthorizeCore(filterContext.HttpContext))
            {
                // ** IMPORTANT **
                // Since we're performing authorization at the action level, the authorization code runs
                // after the output caching module. In the worst case this could allow an authorized user
                // to cause the page to be cached, then an unauthorized user would later be served the
                // cached page. We work around this by telling proxies not to cache the sensitive page,
                // then we hook our custom authorization code into the caching mechanism so that we have
                // the final say on whether a page should be served from the cache.

                HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
                cachePolicy.SetProxyMaxAge(new TimeSpan(0));
                cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
            }
            else
            {
                //handle no permission
            }
        }

        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
        {
            validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
        }
    }

然后像这样使用它:

[AuthorizeEntryPermission(Permission = "Edit")]
public ActionResult Edit(int? Id){
    //edit action
}

答案 1 :(得分:1)

MVC内置了角色。您可以根据需要使角色成为粒度 - 基本上使它们像权限一样。例如,您可以创建角色名称,如:

  • EditBlogPost
  • AddBlogPost
  • ViewBlogPost

然后,您可以使用内置的AuthorizeAttribute在控制器上设置角色。

[Authorize(Roles = "AddBlogPost")]
public ActionResult Add(){
    //add action
}

[Authorize(Roles = "AddBlogPost")]
[HttpPost]
public ActionResult Add(BlogModel model){
    //add action
}

[Authorize(Roles = "EditBlogPost")]
public ActionResult Edit(int? Id){
    //edit action
}

[Authorize(Roles = "EditBlogPost")]
[HttpPost]
public ActionResult Edit(BlogModel model){
    //edit action
}

[Authorize(Roles = "ViewBlogPost")]
public ActionResult View(){
    //view action
}

然后,只需为数据库中的每个用户分配不同的角色即可。

答案 2 :(得分:1)

我希望你的问题解决到现在为止。但值得添加一个新的解决方案。我已为Microsoft Identity 2会员系统实施了基于权限的扩展。它是一个开源项目,你可以在这里访问存储库:

https://github.com/Arminkhodaei/Identity-Permission-Extension

用法:

第一种方法:

// GET: /Manage/Index
[AuthorizePermission(Name = "Show_Management", Description = "Show the Management Page.")]
public async Task<ActionResult> Index(ManageMessageId? message)
{
    //...
}

第二种方法:

// GET: /Manage/Users
public async Task<ActionResult> Users()
{
    if (await HttpContext.AuthorizePermission(name: "AllUsers_Management", description: "Edit all of the users information."))
    {
        return View(db.GetAllUsers());
    }
    else if (await HttpContext.AuthorizePermission(name: "UnConfirmedUsers_Management", description: "Edit unconfirmed users information."))
    {
        return View(db.GetUnConfirmedUsers());
    }
    else
    {
        return View(new List<User>());
    }
}