1 namespace System.Web.Mvc {
3 using System.Diagnostics.CodeAnalysis;
4 using System.Reflection;
7 internal static class SecurityUtil {
9 private static Action<Action> _callInAppTrustThunk;
12 // Do not try to optimize this method or perform any extra caching; doing so could lead to MVC not operating
13 // correctly until the AppDomain is restarted.
14 [SuppressMessage("Microsoft.Security", "CA2107:ReviewDenyAndPermitOnlyUsage",
15 Justification = "This is essentially the same logic as Page.ProcessRequest.")]
16 [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
17 Justification = "If an exception is thrown, assume we're running in same trust level as the application itself, so we don't need to do anything special.")]
18 private static Action<Action> GetCallInAppTrustThunk() {
19 // do we need to create the thunk?
20 if (_callInAppTrustThunk == null) {
22 if (!typeof(SecurityUtil).Assembly.IsFullyTrusted /* bin-deployed */
23 || AppDomain.CurrentDomain.IsHomogenous /* .NET 4 CAS model */) {
24 // we're already running in the application's trust level, so nothing to do
25 _callInAppTrustThunk = f => f();
28 // legacy CAS model - need to lower own permission level to be compatible with legacy systems
29 // This is essentially the same logic as Page.ProcessRequest(HttpContext)
30 NamedPermissionSet namedPermissionSet = (NamedPermissionSet)typeof(HttpRuntime).GetProperty("NamedPermissionSet", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
31 bool disableProcessRequestInApplicationTrust = (bool)typeof(HttpRuntime).GetProperty("DisableProcessRequestInApplicationTrust", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
32 if (namedPermissionSet != null && !disableProcessRequestInApplicationTrust) {
33 _callInAppTrustThunk = f => {
35 namedPermissionSet.PermitOnly();
40 // application's trust level is FullTrust, so nothing to do
41 _callInAppTrustThunk = f => f();
46 // MVC assembly is already running in application trust, so swallow exceptions
50 // if there was an error, just process transparently
51 return _callInAppTrustThunk ?? (Action<Action>)(f => f());
54 public static TResult ProcessInApplicationTrust<TResult>(Func<TResult> func) {
55 TResult result = default(TResult);
56 ProcessInApplicationTrust(delegate { result = func(); });
60 public static void ProcessInApplicationTrust(Action action) {
61 Action<Action> executor = GetCallInAppTrustThunk();