Samantha Branham
Samantha Branham

Reputation: 7441

How do I consume a WS-Security service in WCF over HTTPS?

I'm trying to consume a WS-Security enabled service with WCF. Authentication works using a UsernameToken. I'm not very knowledgeable with WCF web service clients, but I think my configuration below works for regular HTTP communication. I (mostly) used this guide to configure it. The main difference is that I used the VS2010 "Add Service Reference" UI instead of a command prompt.

My problem is that I need to do this over HTTPS. When I use <security mode="Message"> in my app.config, I believe my soap envelope contains the needed WS-Security headers. I can't tell for sure because I can't get logging to work. However, I get the following error: The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via.

Below are the contents of my app.config file, as well as a sample of my client code.

<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="Omitted" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Message">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" negotiateServiceCredential="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://omitted.com/service" binding="wsHttpBinding" bindingConfiguration="Omitted" contract="Omitted.Omitted" name="Omitted" />
</client>
  </system.serviceModel>

var service = new OmittedClient();
service.ClientCredentials.UserName.UserName = "username";
service.ClientCredentials.UserName.Password = "password";    
var response = service.DoSomething(new DoSomethingRequest());

Upvotes: 3

Views: 3823

Answers (1)

Samantha Branham
Samantha Branham

Reputation: 7441

Thanks to 500 - Internal Server error for helping me figure it out. Here are the steps I took:

  1. Generate a proxy using Visual Studio/WCF.
  2. Change the security mode to TransportWithmessageCredential.
  3. Use the following code to specify a username/password.
    var client = new WebServiceClient();
    client.ClientCredentials.UserName.UserName = "USERNAME";
    client.ClientCredentials.UserName.Password = "PASSWORD";
  1. If you get a response back, but WCF complains when processing it, there might be a timestamp missing from the response. If that's the case, try this to fix it.
    // WCF complains about a missing timestamp (http://www.west-wind.com/weblog/posts/2007/Dec/09/Tracing-WCF-Messages)
    var elements = service.Endpoint.Binding.CreateBindingElements();
    elements.Find().IncludeTimestamp = false;
    service.Endpoint.Binding = new CustomBinding(elements);

Upvotes: 1

Related Questions