I am writing a system that consumes a public web service. I'm consuming the web service using VS2008 and classic .NET Framework 2.0 Web Services technology. My problem is not consuming the web service or calling it's operations.
The problem is when I get the response back from the operation it is signed and behind-the-scenes the generated proxy starts verifying the signature. And at that time I get the WSE3003 error. I (think I) have loaded the service certificate into my LocalComputer/TrustedPeople certificate storage and when I look at it's certificate path I can see that all is ok:
VeriSign Class 3 Public Primary CA
www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97...
servcert.there.com
But I keep getting the following exception:
Microsoft.Web.Services3.ResponseProcessingException: WSE910: An error happened during the processing of a response message, and you can find the error in the inner exception. You can also find the response message in the Response property. ---> Microsoft.Web.Services3.Security.SecurityFault: The security token could not be authenticated or authorized ---> System.Security.SecurityException: WSE3003: The certificate's trust chain could not be verified. Please check if the certificate has been properly installed in the Trusted People Certificate store. Or you might want to set allowTestRoot configuration section to true if this is a test certificate.
The following code probably doesn't compile and I have removed some of the sensitive stuff but here is the idea behind how I do my part:
// Construct the wse proxy
MyServiceWse wsClient = new MyServiceWse();
// Assign the credentials
UsernameToken userToken = new UsernameToken("user", "pass", PasswordOption.SendPlainText);
wsClient.SetClientCredential(userToken);
wsClient.RequestSoapContext.IdentityToken = userToken;
// Find the client and service certificates
X509Certificate2 clientCert = MyCertificateManager.FindCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, "mycert.here.com");
X509Certificate2 serviceCert = MyCertificateManager.FindCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, "servicecert.there.com");
// Add the policy to the proxy
Policy policy = new Policy();
MySecurityClientAssertion assertion = new MySecurityClientAssertion();
assertion.SetServiceCertificate(serviceCert);
assertion.SetClientCertificate(clientCert);
policy.Assertions.Add(assertion);
wsClient.SetPolicy(policy);
// Assign the service URL and call an operation
wsClient.Url = "https://services.there.com/TheirService.asmx";
TheirOperationResponse r = wsClient.CallTheirOperation();
I sure hope my code is wrong because I can understand that a lot better than the certificate storage and trust chain stuff. Any help would be great. Thanks for you efforts.