开发者

Problem with WCF client certificates in a ASP.NET application hosted on IIS 7.5

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.

 wcfClient.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySerialNumber, "XXXXXXXXXXXXXXXXXXXXXX");
 // debugging shows that client certificate was found
 var result = wcfClient.CallMyMethod();

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.

Edit: I think the certificate chain might be the issue here...

What I have tried so far:

  1. In MMC: MyCertificate -> All Tasks -> Manage Private Keys... I gave permission for managing private keys to IIS_IUSRS
  2. Added read access to IIS_IUSRS for C:\ProgramData\Microsoft\Crypto\RSA
  3. 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 "We have user-provided certificates. The server has specified 24 issuer(s). Looking for certificates that match any of the issuers." line

ApplicationPoolIdentity Log:

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.

Admin account log:

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=Co开发者_StackOverflow中文版ntinueNeeded).
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]


We had the same issue here. It was solved by ensuring the certificates in the chain were placed in the appropriate locations. Using an administrative account, when installing the certificate into the Personal folder of Local Machine store, it placed the intermediate certs in the same folder. Moving them to the Intermediate Certification Authorities folder provided the ApplicationPoolIdentity access to the complete chain.


As an idea - why not just specify in your web app's config the certificates to send over? If the cert requirements change, simply add to the web.config of your web app. See how the client is setup here for example: http://www.codeproject.com/KB/WCF/Senthil.aspx

<identity><certificate encodedValue="AwAAAAEAAAAUAAAAOTDk6LO4LsMQaY+65EgACb==" /></identity>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜