2012-01-26 79 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); 
} 

這僅僅是一個概念,一個項目我工作的證明,但它似乎是一個可行的解決方案。

相關問題