ASP.Net 使用表单身份验证的网站在回发时抛出安全异常

ASP.Net website using forms authentication throws security exception on postback

我为我的 ASP.net Web 应用程序使用了自定义的基于角色的安全和表单身份验证。角色、用户是从 sql 服务器获取的。该框架针对 4.0 版。

我已经使用了 https://msdn.microsoft.com/en-us/library/ff649337.aspx 中的代码 在登录时创建 FormsAuthenticationTicket,然后我编写了代码以在 Application_PreRequestHandlerExecute 方法中创建一个 GenericPrincipal 对象。

  string cookieName = FormsAuthentication.FormsCookieName;
   HttpCookie authCookie = Context.Request.Cookies[cookieName];
   if (authCookie == null) return;
   FormsAuthenticationTicket authTicket;
  try
  {
    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
  }
   catch (Exception ex)
   {

      throw;
   }
   if (authTicket == null)
    throw new Exception("");

   FormsIdentity id = new FormsIdentity(authTicket);
   if(HttpContext.Current.Session  != null)
   {

   GenericPrincipal principal = new GenericPrincipal(id, new String[]{ "Manager"});

   System.Threading.Thread.CurrentPrincipal = principal;
   }

我已将 PrincipalPermission 属性设置为重定向页面的 page_load 方法

[PrincipalPermissionAttribute(SecurityAction.Demand, Role="Manager")]
protected void Page_Load(object sender, EventArgs e)
{

}

我在此页面中添加了一个按钮,以模拟回发。第一次加载时没有安全异常抛出,但如果我单击按钮,则会抛出一个安全异常,说明 "Request for principal permission denied."。

[SecurityException: Request for principal permission failed.]
   System.Security.Permissions.PrincipalPermission.ThrowSecurityException() +3285333
   System.Security.Permissions.PrincipalPermission.Demand() +419
   System.Security.PermissionSet.DemandNonCAS() +117
   RoleBasedSample.About.Page_Load(Object sender, EventArgs e)

但是,如果我将应用程序池设置为经典,这将无法重现。

是否只有当应用程序池设置为集成模式时才会失败?

GenericPrincipal principal = new GenericPrincipal(id, new String[]{ "Manager"}); 
HttpContext.Current.User = principal;
System.Threading.Thread.CurrentPrincipal = HttpContext.Current.User;

这解决了问题,不确定为什么只有当管道设置为集成时才需要这样做,并且在没有此代码的情况下它可以在经典中运行

GenericPrincipal principal = new GenericPrincipal(id, new String[]{ "Manager"}); 
HttpContext.Current.User = principal; 
System.Threading.Thread.CurrentPrincipal = System.Web.HttpContext.Current.User;

这解决了问题,不确定为什么仅当管道设置为集成时才需要这样做,并且在没有此代码的情况下它可以在经典中运行。