1
votes

I've created a ssl/https web service that is hosted in a console application.

For 127.0.0.1:8741 I've added a certificate and I use https://127.0.0.1:8741/MagazinService/ as endpoint. I use Visual Studio Web Development Server for the Silverlight 4 client. Also the console application that hosts the web service is launched from Visual Studio. I do not use IIS at all. I successfully added the service reference to the silverlight client but when I call operations from the server I get a cross domain error.

I have read about clientaccesspolicy.xml and crossdomain.xml and added this files in the whole solution and it does not work.

I am stuck! Please help! Here is the code that I use:

The app.config in the console application (the server/host):

<system.serviceModel>
<services>
  <service behaviorConfiguration="MagazinServiceBehavior" name="SOAP.MagazinVirtual">
    <endpoint address="" binding="customBinding" bindingConfiguration="MagazinServiceBinding" contract="SOAP.IMagazinVirtual">
    </endpoint>
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="https://127.0.0.1:8741/MagazinService/" />
      </baseAddresses>
    </host>
  </service>
</services>
<bindings>
  <customBinding>
    <!-- buffer: 64KB; max size: 64MB -->
    <binding name="MagazinServiceBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00">
      <security authenticationMode="UserNameOverTransport" />
      <binaryMessageEncoding>
      </binaryMessageEncoding>
      <httpsTransport>
      </httpsTransport>
    </binding>
  </customBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="MagazinServiceBehavior">
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <useRequestHeadersForMetadataAddress>
        <defaultPorts>
          <add scheme="https" port="443" />
        </defaultPorts>
      </useRequestHeadersForMetadataAddress>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="SOAP.Validator, SOAP" />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

here

The ServiceReferences.ClientConfig

<configuration>
<system.serviceModel>
    <bindings>
        <customBinding>
            <binding name="CustomBinding_IMagazinVirtual">
                <security authenticationMode="UserNameOverTransport" includeTimestamp="true">
                    <secureConversationBootstrap />
                </security>
                <binaryMessageEncoding />
                <httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
            </binding>
        </customBinding>
    </bindings>
    <client>
        <endpoint address="https://127.0.0.1:8741/MagazinService/" binding="customBinding"
            bindingConfiguration="CustomBinding_IMagazinVirtual" contract="ServiceReference.IMagazinVirtual"
            name="CustomBinding_IMagazinVirtual" />
    </client>
</system.serviceModel>

Here is the code from the silverlight web project , Web.config:

 <system.serviceModel>
    <bindings>
        <customBinding>
            <binding name="CustomBinding_IMagazinVirtual">
                <security defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport"
                    requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true"
                    keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
                    <localClientSettings cacheCookies="true" detectReplays="false"
                        replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
                        replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
                        sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
                        timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
                    <localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
                        maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
                        negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
                        sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
                        reconnectTransportOnFailure="true" maxPendingSessions="128"
                        maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
                    <secureConversationBootstrap />
                </security>
                <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
                    maxSessionSize="2048">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                </binaryMessageEncoding>
                <httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
                    maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
                    bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                    keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
                    realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                    useDefaultWebProxy="true" requireClientCertificate="false" />
            </binding>
        </customBinding>
    </bindings>
    <client>
        <endpoint address="https://127.0.0.1:8741/MagazinService/" binding="customBinding"
            bindingConfiguration="CustomBinding_IMagazinVirtual" contract="ServiceReference.IMagazinVirtual"
            name="CustomBinding_IMagazinVirtual" />
    </client>
</system.serviceModel>

This is the code for clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
     <policy>
       <allow-from http-request-headers="*">
         <domain uri="http://*" />
        <domain uri="https://*" />
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true" />
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

And this is the code for crossdomain.xml

<?xml version="1.0" encoding="utf-8" ?>
<cross-domain-policy>
    <allow-http-request-headers-from domain="*" headers="SOAPAction" secure="true" />
 </cross-domain-policy>

I am having a hard time with this, please help!

1

1 Answers

0
votes

you need to add a service which can return that xml when a call to the filename at the root of your site is made, as this is what silverlight will do.

When hosted in IIS having the actual file is enough as IIS will serve it when the request to host.name.com/clientaccesspolicy.xml is made. when self hosting this won't be done by default so you need to add stuff to ensure that when this call is made the xml is returned correctly.

create a service interface:

[ServiceContract]
public interface ICrossDomainService
    {
    [WebGet (UriTemplate = "clientaccesspolicy.xml")]
    Stream ProvidePolicyFile ();

    [WebGet (UriTemplate = "crossdomain.xml")]
    Stream ProvideDomainFile ();
    }

then an implementation:

public class CrossDomainService : ICrossDomainService
    {
    #region ICrossDomainService Members

    public Stream ProvidePolicyFile ()
        {
        string result =
            @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers=""*"">
        <domain uri=""*""/>
      </allow-from>
      <grant-to>
        <resource include-subpaths=""true"" path=""/""/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>";

        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";

        return new MemoryStream (Encoding.UTF8.GetBytes (result));
        }

    public Stream ProvideDomainFile ()
        {
        string result =
            @"<?xml version=""1.0""?>
<!DOCTYPE cross-domain-policy SYSTEM ""http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"">
<cross-domain-policy>
    <allow-access-from domain=""*"" />
</cross-domain-policy>";

        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";

        return new MemoryStream (Encoding.UTF8.GetBytes (result));
        }

    #endregion
    }

Then host the implementation at the root of your site:

  <service name="CrossDomainService">
    <endpoint address="" behaviorConfiguration="CrossDomainServiceBehavior" binding="webHttpBinding" bindingConfiguration="" contract="ICrossDomainService"></endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8732/"/>
      </baseAddresses>
    </host>
  </service>


  <endpointBehaviors>
    <behavior name="CrossDomainServiceBehavior">
      <webHttp/>
    </behavior>

This works for me in a self hosted environment