0

I have used a custom role-based security with forms authentication for my ASP.net web application. The roles, users are fetched from sql server. The framework is targeted for version 4.0.

I have used the code from https://msdn.microsoft.com/en-us/library/ff649337.aspx to create the FormsAuthenticationTicket upon login and then I have written the code to create a GenericPrincipal object in the Application_PreRequestHandlerExecute method.

  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;
   }

I have set a PrincipalPermission attribute to the page_load method of the redirect page as

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

}

I have added a button in this page, to simulate a postback. Upon first time load there is no security exception throw but if i click on the button there is a security exception thrown stating that "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)

However, this is not reproducible if i set the application pool to classic.

Is there is a reason why it fails only when application pool is set to Integrated mode?

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

This solves the issue, not sure why this is necessary only when the pipeline is set to integrated and it works in classic without this code

kurozakura
  • 2,339
  • 8
  • 28
  • 41
  • GenericPrincipal principal = new GenericPrincipal(id, new String[]{ "Manager"}); HttpContext.Current.User = principal; System.Threading.Thread.CurrentPrincipal = System.Web.HttpContext.Current.User; This solves the issue, not sure why this is necessary only when the pipeline is set to integrated and it works in classic without this code. – kurozakura Jun 22 '17 at 03:38

1 Answers1

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

This solves the issue, not sure why this is necessary only when the pipeline is set to integrated and it works in classic without this code.

kurozakura
  • 2,339
  • 8
  • 28
  • 41