Best Practice Recommendation
Add the following line to your ASPNET.CONFIG or APP.CONFIG file:
<?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <generatePublisherEvidence enabled="false"/> </runtime> </configuration>
Note the ASPNET.CONFIG file is located in Framework Directory for the version of the Framework you are using. For example for a 64-bit ASP.NET application it would be:
For a 32-bit application it would be:
I have seen this a bunch of times while onsite. The problem goes something like this:
When I restart my ASP.NET application the initial page load is very slow. Sometimes upwards of 30+ seconds.
Many people just blame this on “.NET Startup” costs but there is no out of the box reason that an ASP.NET application should take that long to load. Some applications do work on startup which can cause a startup slow down but there are other things that cause slow downs. A common cause that I have seen often recently is Certificate Revocation List (CRL) checking when generating Publisher Evidence for Code Access Security (CAS).
A little background – CAS is feature in .NET that allows you to have more granular control over what code can execute in your process. Basically there are 3 parts:
- Evidence – Information that a module/code presents to the runtime. This can be where the module was loaded from, the hash of the binary, strong name, and importantly for this case the Authenticode signature that identifies a modules publisher.
- Permissions Set – Group of Permissions to give code (Access to File System, Access to AD, Access to Registry)
- Code Group – The evidence is used to provide membership in a code group. Permission Sets are granted to a code group.
So when a module loads it presents a bunch of evidence to the CLR and the CLR validates it. One type of evidence is the “publisher” of the module. This evidence is validated by looking at the Authenticode signature which involves a Certificate. When validating the Certificate the OS walks the chain of Certificates and tries to download the Certificate Revocation List from a server on the internet. This is where the slowdown occurs.
A lot of servers do not have access to make calls out to internet. It is either explicitly blocked, the server might be on a secure network, or a proxy server might require credentials to gain access to the internet. If the DNS/network returns quickly with a failure the OS check will move on but if the DNS/network is slow or does not respond at all to the request we have to timeout.
This can occur for multiple modules because we create this evidence for each module that is loaded. However if we have looked for a CRL and failed we will not recheck. However different certificates have different CRLs. For instance a VeriSign Certificate may have one CRL URL but a Microsoft Certificate will have a different one.
Since this probe can slow things down it is best to just avoid the probe if you do not need it. For .NET the only reason you would need it is if you are setting Code Access Security based on the module Publisher. Because this can cause potential slow downs and you do not need to occur this penalty you can just disable the generation of the Publisher Evidence when your module is loaded. To disable this use the <generatePublisherEvidence> Application configuration. Just set the enabled property to false and you will avoid all of this.
Now for ASP.NET applications it was not immediately obvious how to do this but it turns out that you cannot add this to an applications Web.Config but you can add it to the ASPNET.CONFIG file in the Framework directory. For other applications just add the attribute to the APP.CONFIG file.
In closing there are several blog entries that do a great job of demonstrating how this will show up in the debugger and other details on CRL issues and workarounds:
We are highlighting this as the first in a series of general best practice recommendations.
NOTE – If you have .NET 2.0 RTM you will need this hotfix - http://support.microsoft.com/default.aspx/kb/936707