2
votes

First and foremost, thanks for your time and attention!

I have a WCF web service that requires a x509 certificate for authentication. This web service has been added as a connected service and reference classes generated in a .Net Standard 2.0 Library. I would like to consume this WCF web service. However, what I'm running into is this; the BasicHttpsSecurity object I'm trying to assign to the Security property of the BasicHttpsBinding doesn't appear to have any accessible constructors...

How can I set the ClientCredentialType property to Certificate in this scenario?

In a full .Net Framework test project I made on the side, I have the exact same code working as expected. It appears the binding and the x509 certificate are setup as needed. I just can't set the Security property to specify that I want it to actually use the certificate... :/

Here's the code I'm using to setup the client. It appears to work fine in a full .Net Framework test app. The main concern is that "Security = new BasicHttpsSecurity()" tells me there is no constructor that accepts 0 arguments... However, I'm not seeing any constructors at all. Therefore, I can't tell the binding that I want to use HttpClientCredentialType.Certificate as my ClientCredentialType.

private TestServiceClient GetTestServiceClient()
{
    var address = new EndpointAddress("https://known.to.be/working/service/endpoint");
    var binding = new BasicHttpsBinding()
    {
        Name = "basic_SSL_Cert",

        // ... other properties that work fine in full .Net Framework test.

        // I can't instantiate/initialize this...
        Security = new BasicHttpsSecurity()
        {
            Mode = BasicHttpsSecurityMode.Transport,
            Transport = new HttpTransportSecurity()
            {
                // ... so I can't set this :(
                ClientCredentialType = HttpClientCredentialType.Certificate,
                ProxyCredentialType = HttpProxyCredentialType.None
            }
        }
    };

    var client = new TestServiceCLient(binding, address);

    client.ClientCredentials.ClientCertificate.SetCertificate(
        StoreLocation.LocalMachine, 
        StoreName.My, 
        X509FindType.FindBySubjectDistinguishedName, 
        "I can find the cert no problem."
    );

    return client;
}

Any advice on how to consume a WCF web service that requires an x509 certificate from a .Net Standard 2.0 Library is greatly appreciated. If I'm going about this all wrong, please do steer me straight.

Thanks in advance for your time!

1
enabling the SSL security can be done in configuration file <bindings> <basicHttpBinding> <binding name="defaultBasicHttpBinding"> <security mode="Transport"> <transport clientCredentialType="None"/> </security> </binding> </basicHttpBinding> </bindings>Suhail
@Suhail Thanks for the comment. I have an appsettings.json configuration file rather than a traditional app/web.config. This WCF web service will be called from within an ASPNet Core Web API. I was planning to pluck app settings out of appsettings.json and populate the binding in code. Is there a better way?Urk

1 Answers

1
votes

Well... finally figured it out this morning. And, I'm slightly embarrassed about the answer. But, hopefully this helps some other poor soul banging his/her head against the wall over it.

It turns out that I can set the ClientCredentialType on the binding I created without ever explicitly instantiating and initializing the BasicHttpsSecurity object.

This binding setup works perfectly fine...

private TestServiceClient GetTestServiceClient()
{
    var address = new EndpointAddress("https://known.to.be/working/service/endpoint");
    var binding = new BasicHttpsBinding()
    {
        Name = "basic_SSL_Cert",

        // ... other properties that work fine in full .Net Framework 

        //Security = new BasicHttpsSecurity()
        //{
        //    Mode = BasicHttpsSecurityMode.Transport,
        //    Transport = new HttpTransportSecurity()
        //    {
        //        // ... so I can't set this :(
        //        ClientCredentialType = HttpClientCredentialType.Certificate,
        //        ProxyCredentialType = HttpProxyCredentialType.None
        //    }
        //}
    };

    // Just set it... doh!
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

    var client = new TestServiceCLient(binding, address);

    client.ClientCredentials.ClientCertificate.SetCertificate(
        StoreLocation.LocalMachine, 
        StoreName.My, 
        X509FindType.FindBySubjectDistinguishedName, 
        "I can find the cert no problem."
    );

    return client;
}

How silly of me... I should have at least tried that before posting the question, but I just didn't click with me that it would be possible. :/