'Consuming web service with SSL (https) in C#

I want to consume an ssl secured web service in C#. The request looks like this:

<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:biw="http://tempuri.org/ws_returnTable"
  xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
  >
  <soapenv:Header>
    <wsse:Security>
      <wsse:UsernameToken>
        <wsse:Username>sasdemo</wsse:Username>
        <wsse:Password>sasch.111</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
   <soapenv:Body>
      <biw:meansclass />
   </soapenv:Body>
</soapenv:Envelope> 

The endpoint declaration in WSDL looks like this:

<wsdl:service name="meansclass">
  <wsdl:port binding="tns:meansclassSoapBinding" name="meansclassPort">
    <soap:address location="https://sas.ssz.intra.stzh.ch:8443/SASBIWS/services/Shared%20Data/ws/meansclass" /> 
  </wsdl:port>
</wsdl:service>

The app.config looks like this:

<bindings>
    <basicHttpBinding>
        <binding name="meansclassSoapBinding" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                maxBytesPerRead="4096" maxNameTableCharCount="16384" />
            <security mode="Transport">
                <transport clientCredentialType="None" proxyCredentialType="None"
                    realm="" />
                <message clientCredentialType="UserName" algorithmSuite="Default" />
            </security>
        </binding>
    </basicHttpBinding>
</bindings>
<client>
    <endpoint address="https://localhost:8443/SASBIWS/services/Shared%20Data/ws/meansclass"
        binding="basicHttpBinding" bindingConfiguration="meansclassSoapBinding"
        contract="ServiceReference1.meansclassPortType" name="meansclassPort" />
</client>

I tried to access the web service with that C# code:

var service = new meansclassPortTypeClient();

service.ClientCredentials.UserName.UserName = "username";
service.ClientCredentials.UserName.Password = "password";

var test = service.meansclass();

But there is always an exception thrown by meansclass(). In German it says:

Exception of type 'Client Authentication' (...) There is no security context.

I have googled a lot but haven't found out what I do wrong. How can I make such a "security context"? Or what is wrong?



Solution 1:[1]

Without additional context (view of the WSDL) I am grasping, but it is possible that you are confusing SSL security with web service security and the service is complaining about unexpected credentials in the SOAP header.

SSL security is applied as part of the process of transporting the web service request and response. The requirement to coordinate an SSL interaction is trust of the server's certificate by the client by pulling the cert into the trust store being used by C#.

What is shown in the request is a 'message level' wss (web service security) username/password credential.

Suggestions:

  1. If you have control of the service implementation, ensure that any security policies are removed from the web service. If you do not, and you are not absolutely certain that the username and password are required for service consumption, remove the username and password from the soap header.
  2. Again if you have control of the service implementation, try removing the SSL requirement and exercising the service to determine if the service can be called over an unsecured (http) connection.
  3. Add back in just the SSL and check for exceptions...remembering that the public certificate for the server must be trusted by the context in which C# is running. The cert can generally be obtained by visiting the web service (https) address in a browser and using the browser's mechanism to save the cert into the appropriate trust store (http://balajiramesh.wordpress.com/2007/12/28/save-ssl-certificate-to-cer-file/)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 dcbyers