Search code examples
c#httpwebrequestapplicationpoolidentity

HttpWebRequest, TLS and application pool service identity


We use HttpWebRequest to make web service calls to a remote server. The call requires a certificate to be loaded from the local machine.

The problem we are running into is if the Application Pool identity is set to NetworkService then the call fails with a generic TLS/SSL error on the HttpWebResponse.GetResponse() call. If we change the identity of the app pool user to LocalSystem then it functions normally.

What I'm trying to figure out is why. What does LocalSystem have access to that NetworkService doesn't which is impacting a post call?

The code is pretty simple:

    string URL = "https://mywebserver.net";
    X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);

    var certResults = store.Certificates.Find(X509FindType.FindBySubjectName, "nameofthecertificate", false);

    /* I have confirmed that the certificate is found regardless of 
     * how the application pool is configured.
    */
    X509Certificate cert = certResults[0];

    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);

    req.AllowAutoRedirect = true;

    req.ClientCertificates.Add(cert);

    req.Method = "POST";

    req.ContentType = "application/soap+xml;charset=UTF-8";

    StringBuilder postData = new StringBuilder();
    postData.Append("some soap info");

    byte[] postBytes = Encoding.UTF8.GetBytes(postData.ToString());

    using (Stream postStream = req.GetRequestStream())
    {
        postStream.Write(postBytes, 0, postBytes.Length);
        postStream.Flush();
        postStream.Close();
    }

    // dies here when running under NetworkService
    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
    String data = String.Empty;

    using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
    {
        data = reader.ReadToEnd();
        reader.Close();
    }

Solution

  • Generally speaking, an Application Pool needs an Identity to run under. You could configure the identity for it to run as you did, but bear in mind that the different identities have different levels of permission.

    Your problem could be as simple as the application pool identity not having permissions for using the code it's trying to execute. You can check that by viewing the deployed projects folder permissions to see.

    Since you mentioned SSL/TLS errors, I would be thinking the identity does not have permission on the installed certificate. Open up mmc and check to see if have the certificate in the Local Computer/Personal/Certificates store. If you do, right click on the certificate and go to All Tasks -> Manage Private Keys.... Add in the Application pool identity by adding it from your computer location as:

    IIS AppPool\YourNameOfAppPool.

    You should not get another dialog saying it wasn't found it you added it correctly.

    Read more about the Application pool identities here.