2011-06-06 78 views
1

我創建了一個託管在控制檯應用程序中的ssl/https web服務。在Silverlight中使用wcf安全的自託管服務

對於127.0.0.1:8741我已經添加了一個證書,我使用https://127.0.0.1:8741/MagazinService/作爲終點。我使用Visual Studio Web Development Server作爲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> 

我有一個很難與此,請大家幫忙!

回答

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> 

這對我的作品在自我託管的環境

+0

好的,我創建了這項新服務。我現在必須做什麼?我是否必須向Silverlight客戶端添加服務引用,指向新創建的服務?我是否需要從CrossDomainService調用方法?第一個服務是受保護的服務,位於https://127.0.0.1:8741,我現在創建的服務正在監聽http:// localhost:8732。這樣可以嗎? – lex87 2011-06-06 14:08:59

+0

我添加了對新建服務的引用。現在看起來完成的事件是在從安全服務調用方法後觸發的,但我仍然有相同的跨域異常。我不知道我做錯了什麼。 – lex87 2011-06-06 14:18:07

+0

你應該不需要做任何事情。他們都應該運行在我認爲的同一個端口上。嘗試將跨域服務更改爲在8741上運行。 – 2011-06-06 14:21:00