A common scenario for developers is that they create an assembly that is to be hosted by Internet Explorer, but requires more trust than would be given to it by default by the Internet or LocalIntranet zone code groups.  Often the first attempt at fixing this involves signing the assembly with a strong name or an X509 certificate and then creating a code group that gives that signature full trust.  Developers are often surprised when they continue to see security exceptions thrown even after they do this.

The reasoning behind the security exception is AppDomains.  Before IE can load your assembly, it must create an AppDomain to load the assembly into.  When it creates this AppDomain, it assigns it all the evidence it knows without loading your assembly, the URL and zone that it is loading from.  Since the AppDomain itself does not get any evidence about the signature that your assembly has (it can't since the assembly is not loaded yet), it will not match the code group that you created giving extra trust.  Now when a security demand occurs, a stack walk begins.  When your assembly is checked for correct permissions, it passes, and the stack walk continues until it gets to the AppDomain.  Since the AppDomain doesn't have the permissions that are required by this demand, it causes the SecurityException to be thrown.

There are two ways to work around this problem.  The first way is to create a code group that matches the evidence that the AppDomain is getting, using a SiteMembershipCondition or a ZoneMembershipCondition, and trust that.  The other is to Assert() all the permissions that your assembly needs at its entry points.  This prevents the stack walk from getting to the AppDomain level, therefore preventing the AppDomain from causing a SecurityException to be thrown.