2012-12-12 26 views
8

我的MVC應用程序在單個頁面請求期間在多個位置使用用戶角色。我的問題是默認的SqlRoleProvider是否在頁面請求的生命週期中緩存當前用戶的角色?角色提供者緩存每個請求?

例如,我做的屬性角色的使用控制器上的方法:

[Authorize(Roles = "Admin")] 

和自定義代碼

if (user.IsInRole(MembershipRole.Admin)) 
{ 
    // Do something 
} 
else if (user.IsInRole(MembershipRole.Printer)) 
{ 
    // Do something else 
} 

如果角色提供程序不緩存角色,是寫的最好的解決辦法一個自定義的角色提供程序,它從默認的角色提供程序繼承,並覆蓋方法來獲取角色一次並緩存它們的請求持續時間?這可以通過Authorize屬性和我自己的代碼將使用緩存角色的方式來完成嗎?

(如果您想知道,我不想使用cacheRolesInCookie web.config選項來緩存cookie中的角色)。

在此先感謝您的任何建議。

[編輯包括從喬的回答引發詳情]

我反編譯System.Web.Mvc.AuthorizeAttribute和AuthorizeCore方法調用下面的方法進行檢查每一個角色:

httpContext.User.IsInRole 

然後查看System.Web.Security.RolePrincipal(這就是上面的「User」),以下兩種方法確實使用用戶角色的緩存副本(或者如果爲空,則填充緩存):

緩存存儲爲用戶的字段,因此其生存期是在請求期間。

Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name) 

所以會使用任何角色提供您所選擇的應用程序(默認或自定義):

的方法使用發現的角色。

回答

6

如果您在ASP.NET或ASP.NET MVC應用程序中使用RoleProvider,然後HttpContext.User將引用RolePrincipal這確實緩存角色請求的生命週期。

然而,在使用ASP.NET角色一個WCF服務:

<behavior ...> 
    <serviceAuthorization principalPermissionMode ="UseAspNetRoles" 
        roleProviderName ="MyRoleProvider" /> 
</behavior> 

這是不正確的:不是HttpContext.User將引用內部類System.ServiceModel.Security.RoleProviderPrincipal,它不會緩存角色相反,它總是調用RoleProvider.IsUserInRole

開箱即用的RoleProviders不執行任何緩存,因此可能導致與基礎數據存儲的重複連接。對我來說這似乎是一個缺陷:在首次訪問時緩存角色本來就很容易。

是編寫自定義的角色提供從默認的繼承和重載的方法來獲取角色一次緩存他們的請求持續時間的最佳解決方案?

不需要ASP.NET或ASP.NET MVC,但可以設想爲WCF。請求持續時間的高速緩存大概會使用HttpContext.Items,因此會引入對HttpContext存在的依賴性,但除了使單元測試更難以外,這不一定是問題。

這可以以Authorize屬性和我自己的代碼都可以使用緩存角色的方式完成嗎?

如果您配置您的自定義RoleProvider在web.config中沒有什麼更多你需要做的,以便Authorize屬性將使用它。

+2

感謝您的想法。 RolePrincipal上的MSDN文檔說:「如果CacheRolesInCookie爲false,則RolePrincipal對象始終使用角色提供程序查找角色成員資格。」當你說RolePrincipal「在請求的生命週期中緩存角色」時,我可以問你如何知道這些(反射,SQL分析,文檔等),因爲它似乎與MSDN相矛盾? – Appetere

+0

@Steve,我通過查看實現(Lutz Reflector或ILSpy)以及實現自定義提供者的經驗來了解這一點。這與MSDN不矛盾:RolePrincipal使用角色提供程序查找角色成員 - 它調用RoleProvider.GetRolesForUser,但每個請求只調用一次,將結果緩存在HybridDictionary字段中。 WCF的RoleProviderPrincipal不調用RoleProvider.GetRolesForUser,而是始終調用RoleProvider.IsInRole,並且不實現任何角色緩存。 – Joe

+0

謝謝你。我遵循你的方法並反編譯相關程序集以查看實際發生的情況。添加一些細節到我原來的問題,以添加到您的答案。 – Appetere