2012-12-12 12 views
8

MVC uygulamam, tek tek sayfa istekleri sırasında birden çok yerde Kullanıcının Rolünü kullanıyor. Benim sorum, varsayılan SqlRoleProvider'ın bir sayfa isteğinin ömrü boyunca geçerli Kullanıcı Rollerini önbelleğe alıp almamasıdır? ÖrneğinRol Sağlayıcı önbellek istek başına mı?

, ben Denetleyici yöntemleri özniteliklerde Rollerin faydalanmak:

[Authorize(Roles = "Admin")] 

ve özel kod

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

Rol Sağlayıcı rollerini önbelleğe etmezse, yazmak için en iyi çözümdür Varsayılan olandan devralan özel bir Rol Sağlayıcısı ve Rolleri bir kez alma ve İstek süresi için önbelleğe alma yöntemlerini geçersiz kılma Bu, hem Authorize özniteliği hem de kendi kodumun önbelleğe alınan rolleri kullanacağı şekilde yapılabilir mi?

(Eğer merak ediyorsanız, çerezlerdeki rolleri önbelleğe almak için cacheRolesInCookie web.config seçeneğini kullanmak istemiyorum).

Öneriniz için şimdiden teşekkür ederiz.

[Düzenle Joe'nun cevabını tetikleyen ayrıntıları içerecek şekilde]

Ben System.Web.Mvc.AuthorizeAttribute ve AuthorizeCore yöntemi her bir rolün kontrol edilecek için aşağıdaki yöntemi çağırır bozulamaz:

httpContext.User.IsInRole 

Daha sonra System.Web.Security.RolePrincipal ("Kullanıcı" nın üstündedir) 'e bakarak aşağıdaki yöntemlerin ikisi de gerçekten kullanıcının rollerinin önbelleğe alınmış bir kopyasını kullanır (veya boşsa önbelleği doldurur):

Önbellek, Kullanıcı üzerinde bir alan olarak saklanır, bu nedenle ömrü, isteğin süresi içindir.

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

Böylece başvurunun (varsayılan veya özel) için seçmiş olursa olsun rolü sağlayıcı kullanacağız:

yöntemleri kullanarak rolleri bulabilirsiniz.

cevap

6

Bir ASP.NET veya ASP.NET MVC uygulamasında bir kullanırsanız, HttpContext.User, isteğin ömrü boyunca önbellek rollerini yerine getiren bir RolePrincipal referansını kullanır.

Ancak, ASP.NET rollerini kullanan bir WCF hizmeti:

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

bu doğru değildir: onun yerine HttpContext.User rolleri önbelleğe almaz iç sınıfı System.ServiceModel.Security.RoleProviderPrincipal, başvurur: yerine her zaman RoleProvider.IsUserInRole çağırır.

Kutudan çıktı RoleProviders hiçbir önbelleğe alma işlemi yapmaz, bu nedenle bu, temel veri deposuna tekrar tekrar bağlanmaya neden olabilir. Bana bir eksiklik gibi geliyor: ilk erişimde rolleri önbelleğe almak kolay olurdu.

, varsayılan olandan devralan özel Rol Sağlayıcısı yazmak ve Rolleri bir kez almak ve İstek süresi için bunları önbelleğe almak için yöntemleri geçersiz kılmak için en iyi çözümdür? ASP.NET veya ASP.NET MVC için gerekli değildir, ancak WCF için düşünülebilir.

İstek süresi için önbellekleme muhtemelen HttpContext.Items'u kullanır, bu nedenle HttpContext'un varlığına bir bağımlılık getirecektir, ancak bu, birim testini zorlaştırmak haricinde bir sorun değildir.

Bu, hem Authorize özniteliği hem de kendi kodumun önbelleğe alınan rolleri kullanacağı şekilde yapılabilir mi? Eğer web.config'de sizin özel RoleProvider yapılandırırsanız

sen Authorize özellik kullanacak şekilde yapmanız gereken başka bir şey yoktur.

+2

Düşünceleriniz için teşekkür ederiz. RolePrincipal üzerindeki MSDN belgeleri, "CacheRolesInCookie yanlışsa, RolePrincipal nesnesi her zaman rol sağlayıcısı kullanarak rol üyeliği arar." Diyor. RolePrincipal'ın "isteğin ömrü boyunca rolleri önbelleğe aldığını" söylediğinde, MSDN ile çeliştiği göründüğü şekliyle bunu (yansıma, SQL profili, dokümantasyon vb.) Nasıl bildiğinizi sorabilir miyim? – Appetere

+0

@Steve, Uygulamayı (Lutz Reflector veya ILSpy) inceleyerek ve ayrıca özel sağlayıcıları uygulama deneyiminden de biliyorum. Bu, MSDN ile çelişmez: RolePrincipal, rol sağlayıcıyı kullanarak rol taksimi arar - RoleProvider.GetRolesForUser çağırır, ancak yalnızca istek başına bir kez çağırır, bir HybridDictionary alanında sonucu önbelleğe alır. WCF RoleProviderPrincipal RoleProvider.GetRolesForUser çağırmaz, bunun yerine her zaman RoleProvider.IsInRole çağırır ve rollerin herhangi bir önbelleğe alma uygular. – Joe

+0

Bunun için teşekkürler. Yaklaşımınızı takip ettim ve gerçekte ne olduğunu görmek için ilgili meclisleri deşifre ettim. Cevabınıza eklemek için orijinal soruma bazı ayrıntılar eklendi. – Appetere

İlgili konular