thmshd
thmshd

Reputation: 5847

Silverlight automatically choose security transport mode between http and https

Our Silverlight Application can run in both http and https (SSL, using Transport Security) Mode. In our ServiceReferences.ClientConfig file we simply configured our Service Endpoint this way:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="DefaultEndpoint"
                 maxBufferSize="2147483647"
                 maxReceivedMessageSize="2147483647">
          <security mode="None" />
          <!-- Enable for SSL: mode="Transport" -->
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="/services/DefaultService.svc"
                binding="basicHttpBinding"
                bindingConfiguration="DefaultEndpoint"
                contract="OurNamespace.IOurContractAsync"
                name="DefaultEndpoint" />
    </client>
  </system.serviceModel>
</configuration>

The configured Endpoint can be accessed in both Modes. It simply depends in which context the XAP file was loaded: From http://example.com/slpage.html or https://example.com/slpage.html. Unfortunately, we have to manually switch the Security Mode setting between "None" and "Transport". Everything else would already work as desired. When Security Mode is "None" and we access via https, we get an Exception that "..https was provided but http was expected..." and vice versa. Any chance to let Silverlight automatically decide which Security Mode should be used? What is the simplest solution to this problem?

Thanks in advance

Thomas

Upvotes: 3

Views: 1861

Answers (2)

thmshd
thmshd

Reputation: 5847

we finally ended up with the following solution (not exactly what Valentin suggested, but +1 for help!):

The ServiceReferences.ClientConfig contains both binding and endpoint configurations like this:

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="DefaultBinding"
                 maxBufferSize="2147483647"
                 maxReceivedMessageSize="2147483647">
          <security mode="None" />
        </binding>
      </basicHttpBinding>
      <customBinding>
        <binding name="SecureBinding">
          <textMessageEncoding messageVersion="Soap12WSAddressing10" />
          <httpsTransport maxBufferSize="2147483647"
                          maxReceivedMessageSize="2147483647" />
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="/services/DefaultService.svc"
                binding="basicHttpBinding"
                bindingConfiguration="DefaultBinding"
                contract="OurNamespace.IOurContractAsync"
                name="DefaultEndpoint" />
      <endpoint address="/services/DefaultService.svc"
                binding="customBinding"
                bindingConfiguration="SecureBinding"
                contract="OurNamespace.IOurContractAsync"
                name="SecureEndpoint" />
    </client>
  </system.serviceModel>
</configuration>

On initialization, we read the App.Current.Host.Source.Scheme Property. The Service client is generated by the ChannelFactory, the code is similar to this snippet:

protected string EndpointName {
  get {
    return (App.Current.Host.Source.Scheme == "https") ?
      "SecureEndpoint" : "DefaultEndpoint";
  }
}

protected IOurContractAsync CreateInterface() {
  var channelFactory = ChannelFactory<IOurContractAsync>(EndpointName);
  return channelFactory.CreateChannel();
}

Hope this helps!

Best regards, Thomas

Upvotes: 5

Valentin Kuzub
Valentin Kuzub

Reputation: 12093

I think there can be a number of ways one is to provide initparams to SL app from your web pages like

param name="initParams" value="Https=true"

for https page and false for html page. parse it inside SL and set up security mode for endpoint.

You can create/edit endpoint proxy programmatically in your SL app.

Another way could be setting transport behaviour based on link inside SL app without initparams (if begins with https ->transport else none) I believe once sl app is downloaded link should be not relative and this should be a working solution.

You can make a factory method to create service proxy and put this setup proxy logic inside it , which would be simpler than completely removing this serviceconfig file.

You would simply call

MyServiceClient client = Factory.MakeClient() 

and I think its an elegant enough solution. in MakeClient you decide what transport security to use and its done.

Upvotes: 1

Related Questions