首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ASP.NET MVC应用程序条件编辑操作的基于请求的授权设计

ASP.NET MVC应用程序条件编辑操作的基于请求的授权设计
EN

Stack Overflow用户
提问于 2015-08-06 03:42:31
回答 1查看 5.9K关注 0票数 6

使用基于索赔的模型设计了一个ASP.Net MVC应用程序授权。假设我们有一个名为- Product的对象。通常,有4种不同的操作-创建,编辑,删除和视图。授权使用ClaimsAuthorize属性完成。

代码语言:javascript
复制
[Authorize]
public class ProductController : Controller
{

     [ClaimsAuthorize("Product", "VIEW")]
     public List<Product> GetProducts()
     {
         // ....
     }

     [ClaimsAuthorize("Product", "CREATE")]
     public Product CreateNewProduct(Product product)
     {
         //....
     }
}

但在我的例子中,我必须支持不同类型的编辑权限:

  1. 如果同一个用户最初创建了产品,一些用户可以编辑该产品
  2. 如果产品属于特定类别,并且用户也可以访问同一类别,一些用户可以编辑该产品
  3. 一些用户可以编辑所有的产品(这是正常的产品编辑操作)

您如何优雅地授权所有这些编辑操作(最好是上面所示的属性驱动),同时我希望将授权代码与正常的MVC控制器代码和业务逻辑分开。

上面的代码示例在语法上是不正确的,我只是为了解释这个问题,让我知道您的想法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-06 08:54:27

对于您问题的第一部分,基于声明的授权,我已经在this similar question中回答了它。我不想在这里重复。

但对于你的另一个规则,如产品,只能由所有者编辑。您可以为每条规则编写单独的AuthorizeAttribute并将它们应用于您的操作,这是一个简单的示例:

代码语言:javascript
复制
using Microsoft.AspNet.Identity;
public class OwnerAuthorizeAttribute : AuthorizeAttribute
{
    private string _keyName;
    public bool IsPost { get; set; }

    public OwnerAuthorizeAttribute(string keyName)
    {
        _keyName = keyName;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        // imagine you have a service which could check owner of 
        // product based on userID and ProductID

        return httpContext.User.Identity.IsAuthenticated
            && this.ContainsKey
            && _productService.IsOwner(httpContext.User.Identity.GetUserId(),
                int.Parse(this.KeyValue.ToString()));
    }

    private bool ContainsKey
    {
        get
        {
            return IsPost
                ? HttpContext.Current.Request.Form.AllKeys.Contains(_keyName)
                // for simplicity I just check route data 
                // in real world you might need to check query string too 
                : ((MvcHandler)HttpContext.Current.Handler).RequestContext
                     .RouteData.Values.ContainsKey(_keyName);
        }
    }
    private object KeyValue
    {
        get
        {
            return IsPost
                ? HttpContext.Current.Request.Form[_keyName]
                // for simplicity I just check route data 
                // in real world you might need to check query string too 
                : ((MvcHandler)HttpContext.Current.Handler)
                    .RequestContext.RouteData.Values[_keyName];
        }
    }
}

您也可以在其他规则中重复相同的模式。

您可以简单地将自定义属性应用于您的操作:

代码语言:javascript
复制
[OwnerAuthorize("id")]
public ActionResult Edit(int id)
{
    // your code
}

[HttpPost]
// double checking in post back too 
[OwnerAuthorize("id", IsPost = true)]
public ActionResult Edit(Product product)
{
    // your code
}

很明显,您可以在操作中应用一个以上的AuthorizeAttribute。在这种情况下,所有都必须返回true

代码语言:javascript
复制
[ClaimsAuthorize("Product", "EDIT")]
[OwnerAuthorize("id")]
[YetOtherAuthorize]
public ActionResult MyFancyAction(int id)
{
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31846452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档