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
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
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.
Related
my team is developing a silverlight application and we are now switching our solution to https on our server but we would like to use http locally. So, in the XAP file that results when building the app there is a ServiceReferences.ClientConfig having the configuration for the web services that are referenced in the project. The issue is that I would like to have some configuration when I am running it locally and have some other configuration when I deploy it. We decided to alter the ServiceReferences.ClientConfig before building because otherwise it would be encapsulated in the .xap file. We are using msbuild in a bat file to deploy the solution.
The config file:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinaryBinding">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="../../PlatformAdminUtil.svc"
binding="customBinding" bindingConfiguration="CustomBinaryBinding"
contract="PlatformAdminUtil.PlatformAdminUtil" name="CustomBinding_PlatformAdminUtil" />
</client>
</system.serviceModel>
</configuration>
I wish to change the <httpTransport/> tag into <httpsTransport/>.
I'm new on scripting in bat files so I need some help on the script that would manage this.
I have hosted my Wcf services in a windows services, i am able to use it without any issue in my test console application, but when i try using the same service by using service reference in my silverlight application, it is giving me error.
ServiceReferences.ClientConfig has this entry:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
...
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8732/myservices/myservice/"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_myservice"
contract="ServiceReference1.myservice" name="NetTcpBinding_myservice">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
I am getting this error:
Unrecognized element 'netTcpBinding' in service reference configuration. Note that only a subset of the Windows Communication Foundation configuration functionality is available in Silverlight.
Will appreciate your help..
Alpee
Have you Installed WCF Non-HTTP Activation on your IIS?
Found this rather good article on using NetTcpBinding with WCF and Silverlight: http://www.codeproject.com/Articles/311250/NetTcpBinding-Configurations-for-WCF-and-Silverlig
The other thing I noted is that apparently you can't specify security options with Silverlight and netTcp, so have to specify an insecure binding (from that same example):
<bindings>
<netTcpBinding>
<binding name="InsecureTcp" receiveTimeout="Infinite">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
I am really struggling with this one. I have Google'd this and tried most of the solutions without any success.
Some background information:
I have a WPF application which consumes a WCF service. Everything works fine if the service and the application is on the same domain, but as soon as you move the application to another domain, it stops wokiring and gives the following error:
The request for security token could not be satisfied because authentication failed.
I worked through the following article: Making a Service Available Across Domain Boundaries[^], which referred to making use of some XML files, which I did, I have tried placing the XML files (clientaccesspolicy.xml and crossdomain.xml) on the IIS server - this did not make any difference (please note that I did place the files within the root of the web service)?!
I can access the web service (client side), by entering the URL in the browser as well as click on the wsdl link and view the XML, but I cannot get it working from my WPF application!
This is my client side config file content:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IManagmentService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://server.local/ManagementDataProvider/ManagmentService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IManagmentService"
contract="ManagementService.IManagmentService" name="WSHttpBinding_IManagmentService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Could anyone please provide me with some information of how I can access the web service from my application.
Many thanks in advance!
Kind regards,
Okay, so the issue was resolved by making use of (http://msdn.microsoft.com/en-us/library/ms731361.aspx). The issue had nothing to do with cross-domain access. The (http://msdn.microsoft.com/en-us/library/ms731299.aspx) needs to be satisfied by the security token, thus accessing the web service from an unknown domain (unknown to the DNS), .
Well, this was what solved my issue?!
Kind regards,
I have a silverlight app that talks to a WCF service inside of an ASP.NET website. The following code works:
var service = new ChannelFactory<IService>(new BasicHttpBinding()
{
MaxReceivedMessageSize = int.MaxValue
},
new EndpointAddress(Settings.ServiceUrl)).CreateChannel();
But I really want to take advantage of "binary encoding". To run the service with binary encoding, you cannot use the BasicHttpBinding, you need to use a CustomBinding! The following code is used in the same place, but yields an HTTP 415 Unsupported media type status from the web server. In a debugging session, no breakpoints are reached on the server.
var service = new ChannelFactory<IService>(new CustomBinding(new BinaryMessageEncodingBindingElement(), new HttpTransportBindingElement()
{
MaxReceivedMessageSize = int.MaxValue
}),
new EndpointAddress(Settings.ServiceUrl)).CreateChannel();
I need help finding out why this setting doesnt work! BTW here is the service section in my web config on the server side:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="myBinding">
<binaryMessageEncoding />
<httpTransport authenticationScheme="Negotiate"/>
</binding>
</customBinding>
</bindings>
<services>
<service name="myService">
<endpoint address="" binding="customBinding" bindingConfiguration="myBinding" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wcfServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
I figured out how to enable BinaryMessageEncoding, and I can confirm BinaryMessageEncoding works correctly in IIS and visual studio web dev debug server.
The problem was the all-too-common WCF configuration problem. My "service name" was an arbitrary name, but it SHOULD have been the fully qualified name of the service class. Instead of throwing an exception, WCF was exposing the service under some default behavior, and not warning me that the configuration was not valid.
<bindings>
<customBinding>
<binding name="myBinding" >
<binaryMessageEncoding >
<!--readerQuotas are used to set upper limits on message payload-->
<readerQuotas
maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"
/>
</binaryMessageEncoding>
<httpTransport authenticationScheme="Ntlm" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"/>
</binding>
</customBinding>
</bindings>
<services>
<!--the service name must be the fully-qualified name of the service class-->
<service name="MyProgram.DataService">
<!--this line allows metatada exchange-->
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
<endpoint address="" binding="customBinding" bindingConfiguration="myBinding" contract="MyProgram.IDataService" />
</service>
</services>
I don't understand all Silverlight capabilities but at the moment I think your service doesn't work at all. Your custom binding does not have any transport binding element which is mandatory.
Try to change your binding:
<bindings>
<customBinding>
<binding name="myBinding">
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
I have a problem with a my Web service and i need help.
I have a Silverlight project and the ASP part Silverlight.Web. In Silverlight.Web a added a Linq to SQL file, a database userd to validate user login, and a created a service, a asmx file. In Silverlight project a added a Service Reference for my asmx Web Service. After build the ServiceReferences.ClientConfig was created. Whwn i run my project the service is not working with the created ServiceReferences.ClientConfig file:
If i comment this part
will work only if run my project from VisualStudio,but if publish my project on IIS, the service is not working.(i change in ServiceReferences.ClientConfig my service path http://localhost/silverlight/UserLogin.asmx, where my service is published) I get this error:
Error: Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details. at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at SilverlightPowerPoint.UserLoginService.UsersLoginCompletedEventArgs.get_Result()
at SilverlightPowerPoint.Login.uls_UsersLoginCompleted(Object sender, UsersLoginCompletedEventArgs e)
at SilverlightPowerPoint.UserLoginService.UserLoginSoapClient.OnUsersLoginCompleted(Object state)
Source file: http://localhost/Silverlight/SilverlightPowerPointTestPage.aspx
If i run the service from my IIS http://localhost/Silverlight/UserLogin.asmx, i give the parameters and it works, it return me the answer.
What can i do?
Thanck you,
Andrei
ServiceReferences.ClientConfig file:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="UserLoginSoap" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security>
<transport>
<extendedProtectionPolicy policyEnforcement="Never" />
</transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:50470/UserLogin.asmx"
binding="basicHttpBinding" bindingConfiguration="UserLoginSoap"
contract="UserLoginService.UserLoginSoap" name="UserLoginSoap" />
</client>
</system.serviceModel>
It works after i comment this:
<security>
<transport>
<extendedProtectionPolicy policyEnforcement="Never" />
</transport>
</security>