2013-02-14 74 views
25

當我看到我有3個可能的地方插入我的東西在管道我應該在哪裏插入Asp.net WebAPI中的授權?

1)  AuthorizationFilters 

2)  Action Filters 

3)  DelegatingHandler 

其中最明顯的是AuthorizationFilters,在那裏我可以裝飾自己的行動/控制器,我自定義的授權屬性。說.. MyCustomAuthorizationAttribute

由於HTTP消息處理程序處於處理管道的第一階段。把它放在那裏有意義嗎?

現在對我的授權僅僅意味着在驗證之後在頭部給客戶端檢查令牌。

回答

37

更新2014年7月

我原來的答覆覆蓋的WebAPI 1.用的WebAPI 2出現了一些變化,即現在有一個IAuthenticationFilter這意味着你可以將驗證邏輯出DelegatingHandler這是一個小更優雅的。

有一個Nuget項目here,它提供了IAuthenticationFilter的實現,並解釋了它的一些背景介紹。

OWIN中間件,現在也許是實現你的驗證邏輯最好的地方 - 有證書認證here和基本身份驗證OWIN中間件在這裏this blog post前者的例子是最好的一個示例,因爲它演示瞭如何使用基本AuthenticationHandler的類。

關於AuthorizationFilters的建議基本保持不變。

末更新

通常...

使用DelegatingHandler開展認證...即人是誰。使用它來設置線程和用戶上下文的原則,添加聲明等。您也可以在這裏放置授權邏輯,但在相當全球範圍內。我個人總是使用AuthorizationFilters進行授權。

使用AuthorizationFilters將控制器和操作限制爲特定人員。當您可以通過聲明,主體,網址或http請求參數中的信息推斷他們的權限時,可以使用這些參數。默認的授權過濾器可用於限制對匿名用戶或角色的訪問(如果設置爲委派處理程序之類的東西) - 顯然如果您需要它也可以實現您自己的AuthorizationFilters。

當您需要使用消息內容對授權進行決策時,偶爾使用ActionFilters。你需要訪問實體上的一個屬性來決定他們是否有權訪問(顯然要小心這個(!))。

注:

AuthorizationFilters身體的內容之前被稱爲因此讀他們沒有獲得郵件正文作出授權決定,這就是爲什麼ActionFilters特別是OnActionExecuting是用來偶爾加薪認證錯誤。

所以

在你的情況我會放一個簡單的DelegatingHandler把你的頭,並設置本金。

public class CustomAuthenticationMessageHandler : DelegatingHandler 
{ 


    public CustomAuthenticationMessageHandler() 
    { 

    } 

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, 
                  CancellationToken cancellationToken) 
    { 
     Authenticate(request); 

     return base.SendAsync(request, cancellationToken); 
    } 

    protected virtual void Authenticate(HttpRequestMessage request) 
    { 

     var authorisationHeader = request.Headers.Authorization; 

     if (authorisationHeader == null) 
     { 
      return; 
     } 

     //Ensure you are happy with the header contents then 

     { 
      var principal = new GenericPrincipal(//new Identity , //Roles); 
      Thread.CurrentPrincipal = principal; 
      HttpContext.Current.User = principal; 
     } 

    } 
} 

然後使用AuthorizationFilters限制訪問:

[Authorize] 
    public string Get() 
    { 

    } 

    [Authorize(Roles = "Admin")] 
    public string GetAdminOnly() 
    { 

    } 

要註冊的全球認證

config.MessageHandlers.Add(new CustomAuthenticationMessageHandler()); 

這將意味着在每個請求的本金將被設置爲null或有效的身份。它不會處理授權,即不會拒絕訪問任何控制器或操作。

要開始保護資源

無論靶保護控制器和動作與標準或自定義[授權]屬性。或全球註冊:

config.Filters.Add(new AuthorizeAttribute()); 

而且只有白名單您使用[AllowAnonymous]屬性要不安全的控制器和動作。

如果你只想在部分航線

認證然後你就可以修改你的DelegatingHandler一點點的InnerHandler用於路由到正確的控制器例如

public CustomAuthenticationMessageHandler(HttpConfiguration configuration) 
{ 
     InnerHandler = new HttpRoutingDispatcher(configuration); 
} 

然後你可以指定你的路由此處理,像這樣:

config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "myurl", 
      defaults: new {}, 
      constraints: new {}, 
      handler: new CustomAuthenticationHandler(config) 
      ); 
+0

這是否意味着我會檢查每個請求的授權請求中的pipeline..upside是我可以從管道排出如果授權不在那裏......應該根據路由進行配置,假設我可以有一些不需要任何授權/認證的路由。 – 2013-02-14 13:01:44

+0

我會通過註冊消息處理程序config.MessageHandlers將認證添加到每個路由。添加(新的CustomAuthenticationMessageHandler()); 授權很容易以各種方式實施。如果您的大多數站點都是安全的,則一種方法是在全局範圍內註冊Authorize過濾器config.Filters.Add(new AuthorizeAttribute());然後在控制器上添加[AllowAnonymous]屬性或您想要保留不需要的操作。 – 2013-02-14 13:17:16

+1

你如何得到這個與Self WebApi一起工作? – 2014-01-28 21:51:25