使用基于索赔的模型设计了一个ASP.Net MVC应用程序授权。假设我们有一个名为- Product的对象。通常,有4种不同的操作-创建,编辑,删除和视图。授权使用ClaimsAuthorize属性完成。
[Authorize]
public class ProductController : Controller
{
[ClaimsAuthorize("Product", "VIEW")]
public List<Product> GetProducts()
{
// ....
}
[ClaimsAuthorize("Product", "CREATE")]
public Product CreateNewProduct(Product product)
{
//....
}
}但在我的例子中,我必须支持不同类型的编辑权限:
您如何优雅地授权所有这些编辑操作(最好是上面所示的属性驱动),同时我希望将授权代码与正常的MVC控制器代码和业务逻辑分开。
上面的代码示例在语法上是不正确的,我只是为了解释这个问题,让我知道您的想法。
发布于 2015-08-06 08:54:27
对于您问题的第一部分,基于声明的授权,我已经在this similar question中回答了它。我不想在这里重复。
但对于你的另一个规则,如产品,只能由所有者编辑。您可以为每条规则编写单独的AuthorizeAttribute并将它们应用于您的操作,这是一个简单的示例:
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];
}
}
}您也可以在其他规则中重复相同的模式。
您可以简单地将自定义属性应用于您的操作:
[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。
[ClaimsAuthorize("Product", "EDIT")]
[OwnerAuthorize("id")]
[YetOtherAuthorize]
public ActionResult MyFancyAction(int id)
{
}https://stackoverflow.com/questions/31846452
复制相似问题