ServiceStack Soap 1.2 HTTPS Client
Asked Answered
I

3

9

I have a ServiceStack based Soap Client, which operates correctly for HTTP but when I try to use HTTPS it gives me this error

ServiceStack.WebServiceException: The provided URI scheme 'https' is invalid; ex
pected 'http'.
Parameter name: via ---> System.ArgumentException: The provided URI scheme 'http
s' is invalid; expected 'http'.
Parameter name: via
   at System.ServiceModel.Channels.HttpChannelFactory`1.ValidateCreateChannelPar
ameters(EndpointAddress remoteAddress, Uri via)
   at System.ServiceModel.Channels.HttpChannelFactory`1.OnCreateChannelCore(Endp
ointAddress remoteAddress, Uri via)
   at System.ServiceModel.Channels.ChannelFactoryBase`1.InternalCreateChannel(En
dpointAddress address, Uri via)
   at System.ServiceModel.Channels.ServiceChannelFactory.ServiceChannelFactoryOv
erRequest.CreateInnerChannelBinder(EndpointAddress to, Uri via)
   at System.ServiceModel.Channels.ServiceChannelFactory.CreateServiceChannel(En
dpointAddress address, Uri via)
   at System.ServiceModel.Channels.ServiceChannelFactory.CreateChannel(Type chan
nelType, EndpointAddress address, Uri via)
   at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address
, Uri via)
   at System.ServiceModel.ClientBase`1.CreateChannel()
   at System.ServiceModel.ClientBase`1.CreateChannelInternal()
   at System.ServiceModel.ClientBase`1.get_Channel()
   at ServiceStack.WcfServiceClient.Send(Message message)
   at ServiceStack.WcfServiceClient.Send[T](Object request)
   --- End of inner exception stack trace ---
   at ServiceStack.WcfServiceClient.Send[T](Object request)
   at ElectronicServiceInterface.ESIClient.Login()

I am using a self signed certificate, but I am able to use curl to call my Soap service successfully. This to me indicates that the issue is at the client end.

My code goes along the lines of

using (var client = new Soap12ServiceClient(Uri))
{
    var request = new MyRequestObject { Username = Username, Password = Password };
    var response = client.Send<MyResponseObject>(request);
}

The above shows example request/response DTO class usage.

What do I have to do to make it work with HTTPS without using config files, only code?

Isolde answered 16/5, 2015 at 14:0 Comment(2)
please add your code/configuration of the services hosting.Ashlieashlin
@Ashlieashlin There is no config. I have added a little more code, which at least shows the send call that triggers the exception. The soap service itself is not a ServiceStack based service (only client), but regardless the code doesn't get as far as actually hitting the server at the other end.Isolde
S
2

The problem with config file is that it isn't always straightforward and sometimes plain unpractical. On top of this ServiceStack promotes config-less coding model.

I managed to achieve the required functionality with the following SSL-neutral client:

public class SoapServiceClient : Soap12ServiceClient
{
    public SoapServiceClient(string uri) : base(uri)
    {
        if (uri.StartsWithIgnoreCase("https://"))
        {
            var binding = (WSHttpBinding)base.Binding;
            binding.Security.Mode = SecurityMode.Transport;
        }
    }
}
Subtract answered 16/6, 2015 at 7:6 Comment(0)
P
6

I believe your problem is in your config file, try to add to the binding tag. regarding to this ServiceStack.IntegrationTests you should have

<bindings>
            <basicHttpBinding>
                <binding name="Endpoint_BasicHttpBinding" />
            </basicHttpBinding>
            <wsHttpBinding>
                <binding name="Endpoint_WsHttpBinding">
                    <security mode="None">
                        <transport clientCredentialType="None" />
                        <message establishSecurityContext="false" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>

but in this test, it is only configured to work on HTTP not HTTPS so all you have to do is to change <transport clientCredentialType="None" /> to <transport clientCredentialType="transport" />

Pennywise answered 21/5, 2015 at 6:51 Comment(2)
I don't actually have a config file. So creating is probably the way to go. I'll try it thanks.Isolde
you can use the mentioned link in my answer, it will help you to for-fill all needed configurations, also this link could help github.com/ServiceStack/ServiceStack/wiki/Config-APIPennywise
A
3

you need to have 2 separate base addresses, one for the HTTP and one for HTTPS.

you can define it in configuration file or in you code that performs the hosting.

Ashlieashlin answered 26/5, 2015 at 15:48 Comment(2)
How would I do it in code? I'd rather avoid config if I can. It's only a test application nothing serious.Isolde
when you create your service host you need to provide an array of Uris so provide both protocols (new ServiceHost(MyService, new []{"myService/","https://myService"}))Ashlieashlin
S
2

The problem with config file is that it isn't always straightforward and sometimes plain unpractical. On top of this ServiceStack promotes config-less coding model.

I managed to achieve the required functionality with the following SSL-neutral client:

public class SoapServiceClient : Soap12ServiceClient
{
    public SoapServiceClient(string uri) : base(uri)
    {
        if (uri.StartsWithIgnoreCase("https://"))
        {
            var binding = (WSHttpBinding)base.Binding;
            binding.Security.Mode = SecurityMode.Transport;
        }
    }
}
Subtract answered 16/6, 2015 at 7:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.