title: Problem with WCF client certificates in a ASP.NET application hosted on IIS 7.5
body: <p>I have a WCF service that I need to call in a ASP.NET web application hosted on IIS 7.5. This WCF service uses transport security with client certificates. I am provided with a client certificate which I installed using mmc in "Local Computer/Personal" store location. The .pfx installed 2 other certificates (no private key) which are CA for my client certificate with private key. I am assigning the certificate at runtime, because I might have other certificates used with the same web service in the future.</p>
  
  <pre><code> wcfClient.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySerialNumber, "XXXXXXXXXXXXXXXXXXXXXX");
   // debugging shows that client certificate was found
   var result = wcfClient.CallMyMethod();
  </code></pre>
  
  <p>For my web application running under ApplicationPoolIdentity calling the webservice throws MessageSecurityException with a inner WebException (403 Forbidden) as if I wasn't passing the client certificate at all. Actually not setting a valid certificate will through an InvalidOperationException if the configuration demands it. If I run under an administrator account, then no exception is thrown. I need to be able to call the webservice under ApplicationPoolIdentity.</p>
  
  <p>Edit: I think the certificate chain might be the issue here...</p>
  
  <p>What I have tried so far:</p>
  
  <ol>
  <li>In MMC: MyCertificate -> All Tasks -> Manage Private Keys... I gave permission for managing private keys to IIS_IUSRS</li>
  <li>Added read access to IIS_IUSRS for C:\ProgramData\Microsoft\Crypto\RSA</li>
  <li>I've used System.Net tracing and I've compared the logs for ApplicationPoolIdentity and my administrator account. Everything look the same until a certain point below, after "<em>We have user-provided certificates. The server has specified 24 issuer(s). Looking for certificates that match any of the issuers.</em>" line</li>
  </ol>
  
  <p>ApplicationPoolIdentity Log:</p>
  
  <pre><code>System.Net Information: 0 : [5436] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=CredentialsNeeded).
  System.Net Information: 0 : [5436] SecureChannel#20350898 - We have user-provided certificates. The server has specified 24 issuer(s). Looking for certificates that match any of the issuers.
  System.Net Information: 0 : [5436] SecureChannel#20350898 - Left with 0 client certificates to choose from.
  System.Net Information: 0 : [5436] Using the cached credential handle.
  System.Net Information: 0 : [5436] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = fc5d070:1ffd1d0, targetName = ws.allianztiriac.ro, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
  System.Net Information: 0 : [5436] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=349, returned code=ContinueNeeded).
  System.Net Information: 0 : [5436] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = fc5d070:1ffd1d0, targetName = ws.allianztiriac.ro, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
  System.Net Information: 0 : [5436] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=ContinueNeeded).
  System.Net Information: 0 : [5436] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = fc5d070:1ffd1d0, targetName = ws.allianztiriac.ro, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
  System.Net Information: 0 : [5436] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=OK).
  System.Net Information: 0 : [5436] Remote certificate: [bla bla remote certificate]
  System.Net Information: 0 : [5436] SecureChannel#20350898 - Remote certificate was verified as valid by the user.
  </code></pre>
  
  <p>Admin account log:</p>
  
  <pre><code>System.Net Information: 0 : [5952] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=CredentialsNeeded).
  System.Net Information: 0 : [5952] SecureChannel#60080036 - We have user-provided certificates. The server has specified 24 issuer(s). Looking for certificates that match any of the issuers.
  System.Net Information: 0 : [5952] SecureChannel#60080036 - Selected certificate: [Bla bla bla client cert info]
  System.Net Information: 0 : [5952] SecureChannel#60080036 - Left with 1 client certificates to choose from.
  System.Net Information: 0 : [5952] SecureChannel#60080036 - Trying to find a matching certificate in the certificate store.
  System.Net Information: 0 : [5952] SecureChannel#60080036 - Locating the private key for the certificate: [Bla bla bla client cert info]
  System.Net Information: 0 : [5952] SecureChannel#60080036 - Certificate is of type X509Certificate2 and contains the private key.
  System.Net Information: 0 : [5952] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential)
  System.Net Information: 0 : [5952] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4e5bb48:1fff710, targetName = ws.allianztiriac.ro, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
  System.Net Information: 0 : [5952] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=5718, returned code=ContinueNeeded).
  System.Net Information: 0 : [5952] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4e5bb48:1fff710, targetName = ws.allianztiriac.ro, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
  System.Net Information: 0 : [5952] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=ContinueNeeded).
  System.Net Information: 0 : [5952] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 4e5bb48:1fff710, targetName = ws.allianztiriac.ro, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
  System.Net Information: 0 : [5952] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=OK).
  System.Net Information: 0 : [5952] Remote certificate: [bla bla bla remote certificate]
  </code></pre>