MVC SiteMap Provider Security Trimming + Cache

2019-08-09 19:51发布

问题:

I have setup MVC SiteMap Provider in an ASP.NET MVC project to render a Dropdown Menu. I configured it to use Security Trimming

<add key="MvcSiteMapProvider_SecurityTrimmingEnabled" value="true"/>

It works as expected, i.e., does not show nodes in the menu to which the user does not have access to. However, I am debugging the application and I can see that with each page reload, the breakpoint in the AuthorizeAttribute is being hit X+1 times, where X is the number of nodes that are rendered in the menu (the +1 is the actual HTTP request).

By default, the cache duration parameter is set to 5 minutes. I have also tried explicitly setting the parameter in the Web.config (just in case)

<add key="MvcSiteMapProvider_CacheDuration" value="60" />

It looks like caching is not enabled in the security context.

I saw this old post (from 2010) saying that caching was to be implemented. Can somebody tell me how it is by now?

Thanks.

回答1:

Since there is no built-in user cache, it wouldn't be practical to store page accessibility settings between requests, not to mention caching these settings could potentially put them out of sync with the current context (for example, if the user logs off). Without doing extra work to sync the cache and the current application state, caching security settings always provides an easy way for a hacker to circumvent security.

So the AuthorizeAttribute is called one time per node on each request. Keep in mind that MVC only concerns itself with the current page, but MvcSiteMapProvider must check security for all of the pages in order to determine what nodes to show and hide. However, security trimming performance has been improved considerably in v4 when using the default AuthorizeAttribute. Request caching is done to ensure it is not called more than once per node per request.

If you have made customizations to AuthorizeAttribute, you should take care to make the check as quick as possible and to delegate any response action to a handler (the same way Microsoft does) instead of doing so inside of the custom AuthorizeAttribute.

The one constraint of using a custom AuthorizeAttribute with MvcSiteMapProvider is that it must set the actionContext.Response value to null when authorization succeeds and a non-null value when it fails.