角色提供程序是否按请求缓存?

App*_*ere 8 asp.net asp.net-mvc roleprovider sqlroleprovider

我的MVC应用程序在单个页面请求期间在多个位置使用用户角色.我的问题是默认的SqlRoleProvider是否在页面请求的生命周期中缓存当前用户的角色?

例如,我在Controller方法的属性中使用Roles:

[Authorize(Roles = "Admin")]
Run Code Online (Sandbox Code Playgroud)

和自定义代码

if (user.IsInRole(MembershipRole.Admin))
{
     // Do something
}
else if (user.IsInRole(MembershipRole.Printer))
{
     // Do something else
}
Run Code Online (Sandbox Code Playgroud)

如果角色提供程序不缓存角色,是编写从默认角色继承的自定义角色提供程序的最佳解决方案,并覆盖方法以获取角色一次并在请求持续时间内缓存它们?这可以通过Authorize属性和我自己的代码都将使用缓存的角色来完成吗?

(如果您想知道,我不想使用cacheRolesInCookie web.config选项来缓存cookie中的角色).

在此先感谢您的任何建议.

[编辑以包含Joe回答触发的详细信息]

我反编译了System.Web.Mvc.AuthorizeAttribute,AuthorizeCore方法为每个要检查的角色调用以下方法:

httpContext.User.IsInRole
Run Code Online (Sandbox Code Playgroud)

然后窥视System.Web.Security.RolePrincipal(这就是"User"在上面),下面的方法确实使用了用户角色的缓存副本(或者如果为空则填充缓存):

public string[] GetRoles()
public bool IsInRole(string role)
Run Code Online (Sandbox Code Playgroud)

缓存作为字段存储在User上,因此其生命周期是在请求期间.

方法使用以下方法查找角色:

Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name)
Run Code Online (Sandbox Code Playgroud)

因此将使用您为应用程序选择的任何角色提供程序(默认或自定义).

Joe*_*Joe 6

如果RoleProvider在ASP.NET或ASP.NET MVC应用程序中使用a ,HttpContext.User则将引用RolePrincipal在请求生命周期内执行缓存角色的应用程序.

但是,在使用ASP.NET角色的WCF服务中:

<behavior ...>
    <serviceAuthorization principalPermissionMode ="UseAspNetRoles"
                     roleProviderName ="MyRoleProvider" />
</behavior>
Run Code Online (Sandbox Code Playgroud)

事实并非如此:相反,HttpContext.User它将引用内部类System.ServiceModel.Security.RoleProviderPrincipal,它不会缓存角色:而是始终调用RoleProvider.IsUserInRole.

开箱即用的RoleProviders不进行任何缓存,因此可能导致重复连接到底层数据存储.对我来说这似乎是一个缺陷:在首次访问时缓存角色很容易.

编写自定义角色提供程序是从默认角色继承的最佳解决方案,并覆盖方法以获取角色一次并在请求持续时间内缓存它们?

对于ASP.NET或ASP.NET MVC不是必需的,但可以为WCF设想.可能会使用请求持续时间的缓存HttpContext.Items,因此会引入对存在的依赖HttpContext,但这不一定是一个问题,除了使单元测试更难.

这可以通过Authorize属性和我自己的代码都将使用缓存的角色来完成吗?

如果RoleProvider在web.config中配置自定义,则不需要执行任何操作,以便Authorize属性将使用它.

  • 谢谢你的想法.RolePrincipal上的MSDN文档说:"如果CacheRolesInCookie为false,则RolePrincipal对象始终使用角色提供程序查找角色成员资格." 当你说RolePrincipal"确实在请求的生命周期中缓存角色"时,我可以问你如何知道这些(反射,SQL分析,文档等),因为它似乎与MSDN相矛盾? (2认同)