title: ASP.NET Authentication with Siteminder
body: <p>Our site currently is setup to use windows authentication.  The user security principal is automatically set when the request gets to our code and authorization to specific files is controlled with authorization elements in our web.config.</p>
  
  <p>We've now been mandated to install siteminder on our server to handle authentication.  Because of this the user security principal is not automatically set and our code without modification doesn't know who the user is to determine authorization.</p>
  
  <p>I've developed the following code to solve that problem.  It takes the user name from a header that siteminder injects into the request and it creates a user security principal.</p>
  
  <pre><code>protected void Application_AuthenticateRequest(object sender, EventArgs e)
  
          protected void Application_AuthenticateRequest(object sender, EventArgs e)
          {
              string userSSO = null;
  
              //Siteminder gives us user like in this format domain\user
              userSSO = HttpContext.Current.Request.Headers["SMUser"];
  
              if (userSSO != null &amp;&amp; userSSO != "")
              {
                  //we have to take the id in the format siteminder gives us and switch it over to upn format like this user@domain
                  string [] delimiters = {"\\"};
                  string [] aryUserSSO = userSSO.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                  string UPN = aryUserSSO[1] + "@" + aryUserSSO[0] + "domain.com";
  
  
                  //now we create identity and princal objects using the UPN
                  WindowsIdentity identity = new WindowsIdentity(UPN, "WindowsAuthentication");
  
                  WindowsPrincipal principal = new WindowsPrincipal(identity);
  
                  HttpContext.Current.User = principal;
              }
          }
  </code></pre>
  
  <p>This code works fine so long as the identity of the AppPool on IIS is set to run as LocalSystem.  However, if you set the identity of the AppPool to anything else with fewer permissions like NetworkService or ApplicationPoolIdentity you get the following error message.</p>
  
  <blockquote>
    <h2>Server Error in '/Form1' Application.</h2>
    
    <p>Attempted to perform an unauthorized operation.  Description: An
    unhandled exception occurred during the execution of the current web
    request. Please review the stack trace for more information about the
    error and where it originated in the code. </p>
    
    <p>Exception Details: System.UnauthorizedAccessException: Attempted to
    perform an unauthorized operation. </p>
    
    <p>ASP.NET is not authorized to access the requested resource. Consider
    granting access rights to the resource to the ASP.NET request
    identity. ASP.NET has a base process identity (typically
    {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and
    the configured application pool identity on IIS 7.5) that is used if
    the application is not impersonating. If the application is
    impersonating via , the identity will be
    the anonymous user (typically IUSR_MACHINENAME) or the authenticated
    request user. </p>
    
    <p>To grant ASP.NET access to a file, right-click the file in Explorer,
    choose "Properties" and select the Security tab. Click "Add" to add
    the appropriate user or group. Highlight the ASP.NET account, and
    check the boxes for the desired access.</p>
    
    <p>Source Error: </p>
    
    <p>An unhandled exception was generated during the execution of the
    current web request. Information regarding the origin and location of
    the exception can be identified using the exception stack trace below.</p>
    
    <p>Stack Trace: </p>
    
    <p>[UnauthorizedAccessException: Attempted to perform an unauthorized
    operation.]<br>
    System.Security.Principal.WindowsIdentity.get_AuthenticationType()
    +300    System.Web.Hosting.IIS7WorkerRequest.SetPrincipal(IPrincipal user, IntPtr pManagedPrincipal) +181<br>
    System.Web.HttpContext.SetPrincipalNoDemand(IPrincipal principal,
    Boolean needToSetNativePrincipal) +701<br>
    System.Web.HttpContext.set_User(IPrincipal value) +49<br>
    System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
    +182    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +266</p>
    
    <p>-------------------------------------------------------------------------------- Version Information: Microsoft .NET Framework Version:4.0.30319;
    ASP.NET Version:4.0.30319.1022</p>
  </blockquote>
  
  <p>Also, the event viewer on the servers shows this.</p>
  
  <blockquote>
    <p>The following exception was thrown by the web event provider
    'EventLogProvider' in the application '/Form1' (in an application
    lifetime a maximum of one exception will be logged per provider
    instance):</p>
    
    <p>System.UnauthorizedAccessException: Attempted to perform an
    unauthorized operation.    at
    System.Security.Principal.WindowsIdentity.get_AuthenticationType()<br>
    at
    System.Web.Management.EventLogWebEventProvider.AddWebRequestInformationDataFields(ArrayList
    dataFields, WebRequestInformation reqInfo)    at
    System.Web.Management.EventLogWebEventProvider.ProcessEvent(WebBaseEvent
    eventRaised)    at
    System.Web.Management.WebBaseEvent.RaiseInternal(WebBaseEvent
    eventRaised, ArrayList firingRuleInfos, Int32 index0, Int32 index1)</p>
  </blockquote>
  
  <p>Per this article (<a href="https://stackoverflow.com/questions/8290791/the-following-exception-was-thrown-by-the-web-event-provider-eventlogprovider">The following exception was thrown by the web event provider &#39;EventLogProvider&#39;</a>) I thought the problem must be that my code was trying to write to the EventLog but didn't have permissions.  However, after following the steps outlined in thie artcile (<a href="http://support.thycotic.com/KB/a220/giving-application-pool-access-to-event-log.aspx" rel="nofollow noreferrer">http://support.thycotic.com/KB/a220/giving-application-pool-access-to-event-log.aspx</a>) istill doesn't work.</p>
  
  <p>I'm hoping someone can tell me what it is my code is trying to do on the server that ApplicationPoolIdentity doesn't have access to do and that we can figure out what additional permissions need to be granted to ApplicationPoolIdentity.</p>