我刚刚注意到如何在ASP.NET MVC 5.x站点中使用MVC Sitemap启用安全修整可以大大减慢Web请求。
我从documentation收集到,当security trimming
打开时,MVC站点地图提供程序在站点地图中的每个控制器的实例上创建,以检查该节点是否应该对当前用户可见(每个Web请求)。
我也read,它是根据网络请求缓存,以尽可能降低影响。
当我们的大多数控制器的依赖关系由我们的IoC框架管理为singleton
(意味着获取控制器的实例非常快)时,这种行为过去常常被忽视。
最近,我们的要求发生了变化,我们的大多数依赖都有一个每个Web请求的生活方式,这对MVC Sitemap提供商的性能产生了巨大的负面影响:在我们的开发机器上,mvc站点地图需要超过5秒(!)才能完成它的工作(实例化所有构造函数)。
启用安全修整后,可以采取任何措施加快速度吗?
笔记:
值得一提的是,我们遵循在构造函数appart中没有做任何事情的最佳实践,将参数分配给实例变量或属性)以避免进一步减慢速度。
我们还坚持使用Microsoft提供的默认Authorize属性。
这是我最终实施的解决方案:
restrict-to-role
,这些节点与使用[Authorize(Roles="Role1,Role2")]
属性修饰的控制器操作相匹配。restrict-to-roles
属性的属性。如果有值,我然后调用ASP.NET标识的IsInRole
方法来检查当前用户是否可以看到该节点。public class RolesInXmlFileSecurityTrimmingVisibilityProvider : SiteMapNodeVisibilityProviderBase
{
public override bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata)
{
var isVisible = true;
if (node.Attributes.ContainsKey("restrict-to-roles"))
{
var roles = Convert.ToString(node.Attributes["restrict-to-roles"]);
if (!string.IsNullOrEmpty(roles))
{
// Your implemenation may vary
isVisible = IsInRole(roles);
}
}
return isVisible;
}
}
优点:
这非常快,您无需实例化所有控制器以查找[Authorize]
属性。
退税:
您必须在控制器中的MVC restric-to-roles
之上手动维护MVC站点地图文件中的[Authorize]
属性。