2012-01-11 72 views
2

我目前在使用Windows身份驗證的MVC3應用程序中使用Unity和Unity.Mvc3。我也在閱讀做依賴注入,並試圖建立一個環境上下文進行一些授權檢查。如何在Unity中設置環境上下文DI在MVC3中?

我有一個靜態屬性電流保持一個抽象AuthorizeContext類這個類的三個實施方式中的一種:

  1. AuthorizeRoleContext,用於生產,這需要通過構造器注入的字符串和一個IPrincipal和是隻要一個間接層就可以調用IPrincipal.IsUserInRole,只要有請求或需求進行授權。注入的字符串用作角色的域前綴。

  2. AuthorizeContextAllowAll,用於開發和有時測試,它總是允許使用默認構造函數的所有授權請求和要求。

  3. AuthorizeContextAllowNothing,用於測試總是拒絕所有授權請求的最小允許功能。

  4. 未來,再添加一個,並通過數據庫檢查授權......?

,所以我可以手動線東西通過執行(例如,在的Application_BeginRequest):

AuthorizeContext.Current =新 AuthorizeRoleContext(HttpContext.Current.User);

,然後調用

AuthorizeContext.Current.Demand( 「someRole」);

這個偉大的工程,但是我正在尋找正確的方式(和地點)使用Unity接線起來,同時也避免了服務定位器反模式。所以我的問題是:我該怎麼做?

一些我有統一登記迄今所面臨的挑戰:

  • 我沒有一個HttpContext.Current.User在的Application_Start,所以我不能在那個時候
  • 我把它注射在AuthorizeRoleContext不知道如何實現分配給靜態AuthorizeContext.Current屬性現在

也許我應該只是做[授權(角色=「role1上」)無處不在,只是讓MVC3做它的東西,而是:

  • 我也用它來建立我的菜單,也許想在其他地方使用它進行授權檢查。
  • 我想換出與其他實現(如允許所有)的授權檢查,所以我不必爲每個開發人員/測試人員分配Windows組。
  • 我似乎必須使用與IPrincipal.IsUserInRole的角色的域前綴或不會跨越開發/測試/生產工作。當然,生產是在客戶環境中,使用完全不同的域名。這就是我對域名進行配置並注入的原因。
  • 我想單元測試的東西。

但也許我仍然在這個錯誤的軌道上,我正在解決那些不存在的問題。 :)

+0

如果Unity不參與,你會怎麼做?何時何地分配當前屬性? – 2012-01-11 11:50:55

+1

爲什麼不使用Thread.CurrentPrincipal和現有的框架支持,而不是如果滾動你自己的? – 2012-01-11 11:54:19

+0

組合根將是Application_Start,所以這是我嘗試去做的地方。但是需要一個上下文,我想我可以在Application_BeginRequest中完成。 – nielsvk 2012-01-11 12:04:37

回答

4

我不相信這個額外的間接層添加任何價值。 IPrincipal已經是一個多態的類型,所以你可以用更簡單的方式完成你想要的東西。

而不是AuthorizeRoleContext,您可以使用Windows身份驗證(WindowsPrincipal)提供的IPrincipal。

相反AuthorizeContextAllowAll的你可能只是實現的IPrincipal是這樣的:

public AllowAllPrincipal : IPrincipal 
{ 
    public bool IsInRole(string role) 
    { 
     return true; 
    } 

    // also implement the Identity property... 
} 

相反AuthorizeContextAllowNothing的實現IPrincipal的是這樣的:

public AllowNothingPrincipal : IPrincipal 
{ 
    public bool IsInRole(string role) 
    { 
     return false; 
    } 

    // also implement the Identity property... 
} 

配置它,你可以將它添加到Global.asax中。 cs:

private void OnAuthenticateRequest(object sender, EventArgs e) 
{ 
    this.Context.User = this.container.Resolve<IPrincipal>(); 
} 

要配置Unity w第i個 '真正' 的IPrincipal,你可以將它設置這樣的:

this.container.RegisterType<IPrincipal>(
    new InjectionFactory(
     _ => HttpContext.Current.User)); 

爲了與AllowAllPrincipal配置統一是非常容易:

this.container.RegisterType<IPrincipal, AllowAllPrincipal>(); 

,並同樣與AllowNothingPrincipal:

this.container.RegisterType<IPrincipal, AllowNothingPrincipal>(); 

如果你必須堅持要連接你自己的AuthorizeContext,你可以用類似的方式來完成。

+0

感謝您的解釋標記。它看起來像是一個更簡潔的解決方案,用於更換原理。現在我只需要結合我的其他需求。回到繪圖板。 :) – nielsvk 2012-01-13 13:27:07