2013-10-22 75 views
2

在.NET WebAPI中,我創建了一種將所有授權規則放在中央位置的方法,而不是遍佈控制器。我很好奇爲什麼這種集權不經常做得更多;是否有影響/安全問題?.NET WebAPI集中授權

我目前的做法是在App_Start期間創建一個字典,其中包含我所有的授權數據,然後使用DelegatingHandler應用限制(下面的代碼)。字典密鑰是控制器和操作的元組,並且該值是授權角色。 DelegatingHandler綁定到WebAPI的路由配置中以獲取調用哪個控制器,然後使用Dictionary來確定請求是否被允許。

詞典:

var authorizations = new Dictionary<Tuple<string, string>, string>(); 
authorizations.Add(new Tuple<string, string>("values", "get"), "public"); 
authorizations.Add(new Tuple<string, string>("values", "put"), "private"); 

DelegatingHandler:

public class SecurityDelegateHandler : DelegatingHandler 
{ 
    private readonly Dictionary<Tuple<string, string>, string> _authorizations; 

    public SecurityDelegateHandler(Dictionary<Tuple<string, string>, string> auth) 
    { 
     _authorizations = auth; 
    } 

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     var config = GlobalConfiguration.Configuration; 
     var controllerSelector = new DefaultHttpControllerSelector(config); 
     var descriptor = controllerSelector.SelectController(request); 

     string restrictions; 

     if (!_authorizations.TryGetValue(
       new Tuple<string, string>(descriptor.ControllerName.ToLower(), 
       request.Method.ToString().ToLower()), out restrictions)) 
     { 
      return Task<HttpResponseMessage>.Factory.StartNew(() => 
         request.CreateResponse(HttpStatusCode.Forbidden, 
         "Access denied on unconfigured actions"), 
         cancellationToken); 
     } 

     if (!(Roles.Provider).GetRolesForUser(
       HttpContext.Current.User.Identity.Name).Any(r => 
       restrictions.Contains(r))) 
     { 
      return Task<HttpResponseMessage>.Factory.StartNew(() => 
         request.CreateResponse(HttpStatusCode.Forbidden, 
         "Access Denied"), cancellationToken); 
     } 

     return base.SendAsync(request, cancellationToken); 
    } 
} 

總之,我的問題是:

謝謝!

+0

如何使自定義的AuthorizeFilter註冊爲全局? –

+0

使用全局過濾器可以工作,並且不需要DelegatingHandler。仍然留下使用集中授權是否存在問題的問題。 –

+0

如果它適合您的需求,我不會看到任何問題。如果您對不同的控制器或操作有不同的規則,則多個授權過濾器很有用,但如果它始終是相同的過程,則最好集中它。 –

回答

2

你的方法是一個很好的方法。你應該分開擔憂。這意味着將業務邏輯與非功能邏輯/需求分開(例如記錄,認證,當然還有授權)。

這個問題沒有得到更廣泛的解釋是因爲外部化身份驗證或日誌記錄要比外部化與您的業務更相關的授權要容易得多。

不同的編程框架今天提供了外部授權。微軟擁有基於聲明的授權,Java有幾個框架,例如Spring Security,SunXACML ... PHP有Yii,Ruby有CanCan ...這些框架可以讓你實現基於角色的訪問控制,甚至基於屬性的訪問控制。如果你不熟悉這些術語,請查看NIST的網頁:

如果你想一個解決方案,是技術中立的,即東西,你可以使用對於Java,.NET,PHP ...您可以使用XACML這種可擴展訪問控制標記語言。它與SAML一樣是一個OASIS標準(SAML專注於聯合ID和SSO; XACML專注於細粒度授權)。您可以在OASIS網站和Wikipedia上閱讀關於XACML的更多信息,並在其中嘗試維護該頁面。除了外部授權外,XACML還定義了一種基於策略的授權方法,這是一種非常可擴展的方法。

對於XACML以及像我工作的供應商,如Axiomatics,有幾種開源選項(JBoss,SunXACML,OpenAM ...)。

HTH

+0

聽起來像XACML只是爲了描述政策,但你仍然需要一些東西來實際執行它。如今,這很可能是[OAuth](http://oauth.net/),它在.NET中似乎是[良好支持](http://stackoverflow.com/a/21858612/268066)(也是和其他許多平臺一樣)。而OAuth不需要* XACML - 兩者是正交的。 – CrazyPyro