Search code examples
silverlightwcfclientaccesspolicy.xml

CommunicationException occured due to the fact that my client access policy file was not accessed


I have the a WCF service that is hosted in a console application.
Here's the app.config file:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CAVES.Framework.Network.IntegrationSuite.IntegrationServices.IntegrationServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="CrossDomainServiceBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="CAVES.Framework.Network.IntegrationSuite.IntegrationServices.IntegrationServiceBehavior"
        name="CAVES.Framework.Network.IntegrationSuite.IntegrationServices.IntegrationService">
        <endpoint address="" binding="basicHttpBinding" contract="CAVES.Framework.Network.IntegrationSuite.IntegrationServices.Interfaces.IIntegrationService">

        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8731/IntegrationService" />
          </baseAddresses>
        </host>
      </service>
      <service name="CAVES.Framework.Network.IntegrationSuite.IntegrationServices.CrossDomainService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="webHttpBinding" contract=
"CAVES.Framework.Network.IntegrationSuite.IntegrationServices.Interfaces.ICrossDomainService" behaviorConfiguration="CrossDomainServiceBehavior"/>
      </service>
    </services>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

When I access it with a socket, the client access policy is fetched correctly but when I try to call a method of the IntegrationService it gives me the following exception:

An error occurred while trying to make a request to URI 'http://localhost:8731/IntegrationService'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

Inner exception:
{System.Security.SecurityException ---> System.Security.SecurityException: Security error. at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult) at System.Net.Browser.BrowserHttpWebRequest.<>c_DisplayClass5.b_4(Object sendState) at System.Net.Browser.AsyncHelper.<>c_DisplayClass4.b_1(Object sendState) --- End of inner exception stack trace --- at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state) at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)}

My client access policy file looks fine and it should work and I'm not sure why it doesn't.

<?xml version="1.0" encoding ="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from>
        <domain uri="*" />
      </allow-from>
      <grant-to>
        <socket-resource port="4502-4534" protocol="tcp" />
      </grant-to>
    </policy>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

Solution

  • When I access it with a socket, the client access policy is fetched correctly but when I try to call a method of the IntegrationService it gives me the following exception

    Your cross-domain policy file only allows socket connections from ports 4502 to 4534, but your application is trying to access port 8731. Unless an application is installed out of browser (with elevated privileges), Silverlight can only access this port range, so 8731 won't work.

    Now, your service is using BasicHttpBinding, so I assume you're using HTTP for that. In this case, the policy file must be served in the same domain as the service, and it must be located at the domain root (which in your case would be http://localhost:8731/clientaccesspolicy.xml). The blog post at http://blogs.msdn.com/b/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspx has more information on how to enable cross-domain calls for SL for self-hosted services.