I have been developing a WCF web service recently and in a previous post, I explain how to specify an EndPoint & binding in code. That was a few weeks ago and it’s now time to make the web service run on the customer’s production server, however, to put a spanner in the works, not only did the customer want the web service to run over SSL, they created their own certificate, which forced a browser to show the message, “There is a problem with this website’s security certificate”.
I have two web services in this project, a traditional one (asmx) and the WCF. So the certificate problem caused the asmx web service to fail too, until I found the following piece of code via Google, which I have extended ever so slightly to ensure that the certificate name is as we expected and whether it’s issue date is within bounds (I would attribute it to the author, but far too much water has passed under the bridge and I can’t remember who it was from). The following code goes in the client (the caller) software:
public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy{
public TrustAllCertificatePolicy(){ }
public bool CheckValidationResult(ServicePoint sp, X509Certificate cert,
WebRequest req, int problem)
{
// This is out cert string issuer = "" ; DateTime startDate = new DateTime(1753, 01, 01), endDate = new DateTime(1753, 01, 01); try {
startDate =
Convert.ToDateTime(cert.GetEffectiveDateString()); }
catch { }
try {
endDate =
Convert.ToDateTime(cert.GetExpirationDateString()); }
catch { }
// Check that the issue and cert start & end date are valid if (issuer == cert.Subject && startDate <= DateTime.Now && endDate >
DateTime.Now) return true; else return false;
}}
You can then issue the following piece of code which will call the CheckValidationRequest:
System.ServiceModel.EndpointAddress address = new System.ServiceModel.EndpointAddress(URL); WebServiceClient wService = new WebService.WebServiceClient(new System.ServiceModel.WSHttpBinding(), address); System.Net.ServicePointManager.CertificatePolicy = new WebServiceHelper.TrustAllCertificatePolicy(); Place a breakpoint in the CheckValidationRequest and you’ll see the request being issue.
So, this was perfect for the traditional asmx file, but for the life of me, I couldn’t get this to work for the WCF. I Googled & Googled and found all sorts of weird & wonderful things that you could try and do to your config file to get the certificate to come through, but in the end, I found the following piece of code & config changes were required to get a self cert to work on a WCF web service:
The following line has been altered from above, to tell the TCP layer what type of transport is required:
WebService.WebServiceClient wService = new WebService.WebServiceClient(new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.Transport), address);Notice how we need to tell the WSHttpBinding class, the transport mechanism.
Finally, in the web.config file of your WCF web service, you’ll need the following:
behaviors> section --> <bindings> <
wsHttpBinding> <
binding name="TransportSecurity"> <
security mode="Transport"> <
transport clientCredentialType="None"/>
security>
binding>
wsHttpBinding>
bindings>
system.serviceModel>
That’s it! As I say, it took me hours to get find these tiny number of lines, but I was elated when I had! The errors that I was getting when running my code were: Could not find a base address that matches scheme http for this endpoint with binding WSHttpBinding ,or The requested service could not be activated
No comments:
Post a Comment