2012-05-03 69 views
9

我有一個名爲AuthoriseAttribute它的構造看起來像這樣的自定義屬性:如何插入方法的參數爲自定義屬性

public AuthoriseAttribute(int userId) 
{ 
    .. blah 
} 

這是使用一種稱爲GetUserDetails()這樣的:

[Authorise(????????)] 
public UserDetailsDto GetUserDetails(int userId) 
{ 
    .. blah 
} 

在運行時,Authorize屬性的存在會導致執行一些授權代碼,這需要用戶的ID。顯然,這可以從GetUserDetails()方法的參數被提取,但是這意味着該授權碼依賴於方法的參數被賦予一個特定的名稱。

我希望能夠將userId參數的實際值傳遞給屬性,以便授權代碼使用傳遞給屬性(即不是方法參數)的值,該值的名稱是已知的。

這樣的事情(不工作):

[Authorise(userId)] 
public UserDetailsDto GetUserDetails(int userId) 
{ 
    .. blah 
} 

這種事可能嗎?

+5

沒有不可能的。屬性是元數據。參數值必須是一個常數值。 – vcsjones

+0

有一些我不明白的 - 你爲什麼要授權一個方法參數?海事組織 - 你可能需要授權方法的調用者 - 這是正確的嗎? – Sunny

+2

您所描述的內容不能直接完成,因爲我確定編譯器錯誤告訴您。瞭解「授權屬性的存在是如何導致某些授權代碼執行」的工作是有幫助的。你應該可以讓代碼看看userId參數。 –

回答

12

製作vcsjones'評論的答案,這是不可能的。

屬性是元數據;它們在編譯時編譯到程序集中,並且在運行時不會更改。因此,您傳遞給屬性的任何參數都必須是常量;文字,常量變量,編譯器定義等。

這種方法的一種方式是使用像PostSharp這樣的框架或使用Unity Framework滾動自己的屬性來使屬性成爲AOP元素。這將允許您附加該方法的一個「攔截器」通過用屬性裝飾來實現,然後該屬性將在屬性中運行代碼,並且還將知道如何調用包括參數值的方法。查看此博客:http://www.progware.org/Blog/post/Interception-and-Interceptors-in-C-(Aspect-oriented-programming).aspx

+0

你偷了vcsjones的答案,我會獎勵你的!我確實已經把AOP的東西運行起來了;我的問題是告訴攔截器中的代碼在哪裏找到它需要運行授權邏輯的數據,因爲這個屬性可能被用來裝飾不同簽名的多個方法。 – David

+7

我不會說這是偷竊。 +1,以便接受我的評論並將其轉化爲有用的答案。 – vcsjones

+0

+1是一項很好的運動。 – David

14

一個辦法做到這一點_in ASP.NET MVC_與行動的方法(不是一般的屬性)

public class CustomAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     int userId = (int)filterContext.ActionParameters["userId"]; 
    } 
} 
+0

這工作正常,謝謝! –

0

我能通過使用以下內容來解決此問題:

public class AuthorizeAttribute 
{ 
    protected bool RequireIdClaim { get; private set; } 

    public AuthorizeAttribute(bool requireIdClaim = false) 
    { 
     RequireIdClaim = requireIdClaim; 
    } 

    public Authorize() 
    { 
     //regular auth stuff here 

     if (RequireIdClaim) 
     { 
      var routeData = context.ActionContext.Request.GetRouteData(); 
      var requiredIdClaim = Convert.ToInt32(routeData.Values["id"]); 

      //Check here if their user profile has a claim to that Id 
     } 
    } 
} 

然後在具體的方法上你想檢查ID,

[HttpGet] 
[Route("{id}")] 
[Authorize(requireIdClaim: true)] 
public UserDetailsDto GetUserDetails(int userId) 
{ 
    .. blah 
} 

如果你不小心檢查他們的身份證,只是,他們正在驗證

[HttpGet] 
[Route("")] 
[Authorize] 
public bool isLoggedIn() 
{ 
    .. blah 
} 

當然,只要你喜歡,你可以組織你的授權過程,但這個想法讓你因爲它是作爲路由數據傳入的,所以在你的認證過程中得到他們的ID。 這裏更多:https://stackoverflow.com/a/16054886

相關問題