Claim based authorization design for conditional edit operation in ASP.NET MVC App

北城以北 提交于 2019-11-27 06:18:15

问题


Designing an ASP.Net MVC application authorization using claim based model. Lets say that we have an object called - Product. Typically, there are 4 different actions - Create, Edit, Delete and View. Authorization is done using ClaimsAuthorize attribute.

[Authorize]
public class ProductController : Controller
{

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

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

But in my case, I have to support different types of EDIT permissions:

  1. Some Users can Edit the product if the same user has created the Product originally

  2. Some users can Edit the product if the Product belongs to a specific category and the user also has access to the same category

  3. Some users can Edit all the products (this is the normal Product Edit operation)

How do you elegantly authorize all these Edit operations (preferably attribute driven as shown above) and at the same time I want to keep the authorization code separate from the normal MVC controller code and business logic.

[Above code sample is not syntactically correct, I just made it up for the purpose of explaining this question] Let me know your thoughts.


回答1:


For first part of your question, Claim based authorization, I have already answered it in this similar question. And I am not going to repeat here.

But for your another rules like products editable only by owner. You could write separate AuthorizeAttribute for each rule and apply them on your Actions consider this as an simple example:

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];
        }
    }
}

You could repeat same pattern to your other rules too.

And you could simply apply your custom attributes to your actions:

[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
}

It is obvious you could apply more then one AuthorizeAttribute to your actions. In this case all of them must return true.

[ClaimsAuthorize("Product", "EDIT")]
[OwnerAuthorize("id")]
[YetOtherAuthorize]
public ActionResult MyFancyAction(int id)
{
}


来源:https://stackoverflow.com/questions/31846452/claim-based-authorization-design-for-conditional-edit-operation-in-asp-net-mvc-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!