在Silverlight中使用wcf安全自托管服务

时间:2011-06-06 02:38:29

标签: wcf silverlight-4.0

我创建了一个托管在控制台应用程序中的ssl / https Web服务。

对于127.0.0.1:8741,我添加了证书,并使用https://127.0.0.1:8741/MagazinService/作为端点。我将Visual Studio Web开发服务器用于Silverlight 4客户端。承载Web服务的控制台应用程序也是从Visual Studio启动的。我根本不使用IIS。我成功地将服务引用添加到silverlight客户端,但是当我从服务器调用操作时,我收到了跨域错误。

我已经阅读了有关clientaccesspolicy.xml和crossdomain.xml的内容,并在整个解决方案中添加了这些文件,但它不起作用。

我被卡住了!请帮忙!这是我使用的代码:

控制台应用程序(服务器/主机)中的app.config:

<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" />

这里

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>

以下是silverlight Web项目的代码,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>

这是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>

这是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>

我正在努力解决这个问题,请帮忙!

1 个答案:

答案 0 :(得分:0)

您需要添加一个服务,该服务可以在您的站点根目录调用文件名时返回该xml,因为这是silverlight将要执行的操作。

当在IIS中托管时,实际文件已足够,因为IIS将在发出对host.name.com/clientaccesspolicy.xml的请求时为其提供服务。默认情况下,自我托管时不会这样做,因此您需要添加内容以确保在进行此调用时正确返回xml。

创建服务接口:

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

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

然后是一个实现:

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
    }

然后在您网站的根目录中托管实施:

  <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>

这适用于我自己托管的环境