2012-01-26 76 views
7

我用一个AuthorizeAttribute装饰我的控制器动作。在MVC中的AuthorizeAttribute中获取模型数据3

[ServiceAuthorize(Roles="Editor,Publisher,Administrator")] 
public JsonResult Create(NewsArticle newsArticle) 

在我的NewsArticle模型中有一个字段,我想在我的AuthorizeAttribute的OnAuthorize方法中使用。

有没有办法从AuthorizeAttribute的OnAuthorize方法中获取模型?

我认为它可以在AuthorizationContext中找到,但我无法找到它。我知道我可以在ActionExecutingContext中的filter属性中获得它,但这意味着我需要在我的操作中使用另一个筛选器,并且希望能够在单个步骤中执行所有授权。

谢谢。

回答

6

有没有办法从AuthorizeAttribute的OnAuthorize 方法中获取模型?

否,因为OnAuthorization在模型联编程序之前运行。你可以做的是从价值提供者读出的值:

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    var value = filterContext.Controller.ValueProvider.GetValue("someproperty"); 
    ... 
} 
+0

感谢Darin。我认为在我的情况下,“有些特性”可能是“新闻文章”?我会检查一下。 – Perry 2012-01-26 22:36:27

+1

@Perry,不,你认为是错的。它将成为你感兴趣的'NewsArticle'类的一个属性。正如我所说的,由于'OnAuthorization'方法在模型绑定器之前运行,所以在这个阶段你不能真正谈论'NewsArticle'的实例。您可以查看ValueProvider所执行的请求值。当然,在这个阶段他们将以弦乐的形式出现。您可能还需要进行一些额外的解析。 – 2012-01-26 22:37:28

+0

感谢您的澄清。 – Perry 2012-01-26 22:38:36

1

我试图完成同样的事情,基本上是想控制与操作方法的参数属性的授权,作为一个例子:

[MyAuthorize] 
public ActionResult MyAction(
[Require(Permission.Write)] MyCustomObject arg1, 
[Require(Permission.Read)] MyCustomObject arg2 
) { 
    // ... all authorization would be handled before the action is invoked ... 
} 

class MyAuthorize : AuthorizeAttribute { 
    public override void OnAuthorization(AuthorizationContext filterContext) { 
     // ... filterContext doesn't have the argument objects ... 
    } 
} 

我遇到了同样的问题,当覆盖AuthorzeAttribute.OnAuthorization(...)模型绑定参数尚不存在。为了实现我所需要的,我实现了IActionFilter,它公开了一个方法OnActionExecuting,它将在模型被绑定之后但在调用动作之前调用。我的原型实现是这样的:

class MyAuthorizeAttribute : AuthorizeAttribute, IActionFilter { 

    public override void OnAuthorization(AuthorizationContext filterContext) { 
     // ... I guesss this isn't really needed any more. 
     // the auth check is handled in OnActionExecuting. 
    } 

    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) { 

    } 

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { 

     foreach (var param in filterContext.ActionDescriptor.GetParameters()) { 
      var attr = (RequireAttribute)param.GetCustomAttributes(typeof(RequireAttribute), false).FirstOrDefault(); 
      if(attr != null) { 
       Object obj; 
       if (filterContext.ActionParameters.TryGetValue(param.ParameterName, out obj)) { 
        var sec = obj as ISecurable; 
        if (sec == null || !sec.HasPermission(filterContext.RequestContext, attr.Permission)) { 
         filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.Unauthorized);         
        } 
       } 
      } 
     } 
    } 
} 

interface ISecurable { 
    bool HasPermission(Permission permission); 
} 

这仅仅是一个概念,一个项目我工作的证明,但它似乎是一个可行的解决方案。

相关问题