开始使用带有证书身份验证的WCF路由 - 卡在XML地狱中

时间:2012-04-12 10:37:57

标签: c# wcf wcf-routing

我有一个简单的WCF客户端 - >服务器结构,客户端引用服务器的WCF服务。使用X509证书进行身份验证。

我想为我的服务添加一种简单的冗余形式。意思是 - 要运行多个服务器,并让客户端使用一个路由器,如果主服务器已经死了,它将透明地故障转移到备份服务器。
简单吧?

我使用了hello world示例代码,只是更改了路由器的app.config文件,使其类似于我的客户端。
然后我指着我的客户端在路由器上。

我获得的唯一奖励是An insecured or incorrectly secured fault例外,内部例外说:
The message could not be processed. This is most likely because the action 'http://www.MyCompany.com/MyApp/api/IMyCompanyMyAppService/GetItems' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.

显然,所有这些原因都是公然的谎言(GetItems方法 实现,绑定不匹配,因为我从客户端配置中复制粘贴它们,并且没有任何结果我收到超时错了)。

现在我不知道该怎么做;我有预感这可能与我使用的身份验证方法(X509证书)有关,但我真的没有线索。

附上服务器,路由器和客户端的配置。

<!--SERVER CONFIGURATION-->
  <system.serviceModel>
    <bindings>

            <basicHttpBinding>
        <binding name="MyAppService_BasicHttpBindingConfigurationSSL" 
                                 maxBufferPoolSize="1073741824" maxBufferSize="1073741824" maxReceivedMessageSize="1073741824">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1073741824"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport">
            <transport clientCredentialType="Basic" proxyCredentialType="None"/>
          </security>
        </binding>
      </basicHttpBinding>

      <wsHttpBinding>
        <binding name="MyAppService_BindingConfiguration" maxBufferPoolSize="1073741824" maxReceivedMessageSize="1073741824">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1073741824"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Message">
            <transport/>
            <message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false"/>
          </security>
        </binding>
        <binding name="MyAppService_BindingConfigurationOverSSL" maxBufferPoolSize="1073741824" maxReceivedMessageSize="1073741824">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1073741824"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="TransportWithMessageCredential">
            <transport/>
            <message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <services>
      <service name="MyCompany.MyApp.MyAppService.Server.Service.MyCompanyMyAppService" behaviorConfiguration="MyAppService_Behavior">
        <!-- Non-SSL endpoint -->
        <endpoint name="MyAppServiceEndpoint"
                                    address="http://localhost:8087/MyAppService" 
                                    binding="wsHttpBinding" 
                                    bindingNamespace="http://www.MyCompany.com/api/binding" 
                                    bindingConfiguration="MyAppService_BindingConfiguration" 
                                    behaviorConfiguration="WSDLBehavior" 
                                    contract="MyCompany.MyApp.MyAppService.Common.Services.IMyCompanyMyAppService"/>
        <!-- SSL endpoint -->
        <endpoint name="MyAppServiceEndpointSSL" 
                                    address="https://localhost:8088/MyAppService" 
                                    binding="wsHttpBinding" 
                                    bindingNamespace="http://www.MyCompany.com/api/binding" 
                                    bindingConfiguration="MyAppService_BindingConfigurationOverSSL" 
                                    behaviorConfiguration="WSDLBehavior" 
                                    contract="MyCompany.MyApp.MyAppService.Common.Services.IMyCompanyMyAppService"/>
        <!--BasicHttpBinding-->
        <!--SSL BasicHttpBinding -->
        <endpoint name="MyAppServiceEndpointBasicSSL" 
                                    address="https://localhost:8088/MyAppServiceBasic" 
                                    bindingConfiguration="MyAppService_BasicHttpBindingConfigurationSSL" 
                                    binding="basicHttpBinding" 
                                    contract="MyCompany.MyApp.MyAppService.Common.Services.IMyCompanyMyAppService" />
        <!-- Non-SSL Metadata endpoint -->
        <endpoint name="MyAppServiceBinding" address="http://localhost:8087/mex" binding="mexHttpBinding" behaviorConfiguration="WSDLBehavior" contract="IMetadataExchange"/>
      </service>
    </services>

    <behaviors>
      <endpointBehaviors>
        <behavior name="WSDLBehavior">
          <!--<wsdlExtensions />-->
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>
        <behavior name="MyAppService_Behavior">
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" 
                                                                        customUserNamePasswordValidatorType="MyCompany.MyApp.MyAppService.Server.Service.MyAppUsernamePasswordValidator, MyCompany.MyApp.MyAppService.Server" />

            <clientCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/>
              <certificate/>              
            </clientCertificate>
            <serviceCertificate storeLocation="LocalMachine" 
                                                                storeName="My" x509FindType="FindBySubjectName" findValue="server.dev.MyApp.MyCompany.com"/>
          </serviceCredentials>
          <!-- Allow the service to handle a high load of calls and sessions -->
          <serviceThrottling maxConcurrentCalls="300" maxConcurrentInstances="500" maxConcurrentSessions="30000"/>
          <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8087/mex" httpsGetEnabled="false" httpsGetUrl="https://localhost:8088/mex"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

<!--ROUTER CONFIGURATION-->  
<system.serviceModel>
    <services>
      <!--ROUTING SERVICE -->
      <service behaviorConfiguration="routingData"
          name="System.ServiceModel.Routing.RoutingService">
        <host>
          <baseAddresses>
            <add  baseAddress="http://localhost:8000/MyAppService"/>
          </baseAddresses>
        </host>
        <endpoint address=""
                  binding="wsHttpBinding"
                  name="reqReplyEndpoint"
                  contract="System.ServiceModel.Routing.IRequestReplyRouter" />
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange"  />
      </service>
    </services>

    <bindings>
      <basicHttpBinding>
        <binding name="MyAppServiceEndpointBasicSSL" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport">
            <transport clientCredentialType="Basic" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <wsHttpBinding>
        <binding name="MyAppServiceEndpoint" maxBufferPoolSize="1073741824" maxReceivedMessageSize="1073741824">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1073741824"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Message">
            <transport/>
            <message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false"/>
          </security>
        </binding>
        <binding name="MyAppServiceEndpointSSL" maxBufferPoolSize="1073741824" maxReceivedMessageSize="1073741824">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1073741824"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="TransportWithMessageCredential">
            <transport/>
            <message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="routingData">
          <serviceMetadata httpGetEnabled="True"/>
          <routing filterTableName="routingTable1" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <client>
      <endpoint address="http://localhost:8087/MyAppService" binding="wsHttpBinding"
        bindingConfiguration="MyAppServiceEndpoint" contract="MyCompanyMyAppService.IMyCompanyMyAppService"
        name="MyAppServiceEndpoint">
        <identity>
          <certificate encodedValue="AwAAAAEAAAAUAAAAS2hv3zJGGxe4T0jo4fwcBgc2fbogAAAAAQAAABYCAAAwggISMIIBf6ADAgECAhDtT0KoiuHcoERR+GfWnIJJMAkGBSsOAwIdBQAwHzEdMBsGA1UEAxMUZGV2LmNybS5sZXZlcmF0ZS5jb20wHhcNMTExMTA5MDgyNDQ2WhcNMTMxMjMwMjIwMDAwWjAmMSQwIgYDVQQDExtzZXJ2ZXIuZGV2LmNybS5sZXZlcmF0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsBWu9R/c65MNdQRDkCi4w5uyxp4Hh5FK0hyUh9LzObQuSuMvqYc+cW1OuI1b4G1RBNOwGOzxUeK+dPX6Q5Y96qcmOk5+eJyPOg2dtHaOujGvaW1MN/sVJPMy6xgCtJ6iSe9xDYYmxcha2quZK3LGGvW3d3/QznBqY+XwK6kbHXAgMBAAGjUDBOMEwGA1UdAQRFMEOAEP3fipkit68H++sodJuSZSWhHTAbMRkwFwYDVQQDExBjcm0ubGV2ZXJhdGUuY29tghAluuQuFlNJpU+Yh7Yf725TMAkGBSsOAwIdBQADgYEAZVECKrndJdjMYnfSb2bCByv24mpgE2yCuhm2Ey+cSEwP31aKrHIVNAcVDPd7k1/R4qsWU6I8PHjVCeCHTMnf+EE/1IV0lbCj/PD/D3by+m/7hEKdtzk6VHJyJLmLyO6fIJc14XPI4qC/KVuUS97UjNpWcICZFgM64Vb7MUW5thE=" />
        </identity>
      </endpoint>
      <endpoint address="https://localhost:8088/MyAppService" binding="wsHttpBinding"
        bindingConfiguration="MyAppServiceEndpointSSL" contract="MyCompanyMyAppService.IMyCompanyMyAppService"
        name="MyAppServiceEndpointSSL" />
      <endpoint address="https://localhost:8088/MyAppServiceBasic" binding="basicHttpBinding"
        bindingConfiguration="MyAppServiceEndpointBasicSSL" contract="MyCompanyMyAppService.IMyCompanyMyAppService"
        name="MyAppServiceEndpointBasicSSL" />
    </client>
    <!--ROUTING SECTION -->
    <routing>
      <filters>
        <filter name="MatchAllFilter1" filterType="MatchAll" />
      </filters>
      <filterTables>
        <filterTable name="routingTable1">
          <add filterName="MatchAllFilter1" endpointName="MyAppServiceEndpoint" />
        </filterTable>
      </filterTables>
    </routing>
  </system.serviceModel>



<!--CLIENT CONFIGURATION-->  
<system.serviceModel>
    <client>
      <endpoint address="http://localhost:8087/MyAppService" binding="wsHttpBinding"
        bindingConfiguration="MyAppServiceEndpoint" contract="MyCompanyMyAppService.IMyCompanyMyAppService"
        name="MyAppServiceEndpoint">
        <identity>
          <certificate encodedValue="AwAAAAEAAAAUAAAAS2hv3zJGGxe4T0jo4fwcBgc2fbogAAAAAQAAABYCAAAwggISMIIBf6ADAgECAhDtT0KoiuHcoERR+GfWnIJJMAkGBSsOAwIdBQAwHzEdMBsGA1UEAxMUZGV2LmNybS5sZXZlcmF0ZS5jb20wHhcNMTExMTA5MDgyNDQ2WhcNMTMxMjMwMjIwMDAwWjAmMSQwIgYDVQQDExtzZXJ2ZXIuZGV2LmNybS5sZXZlcmF0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsBWu9R/c65MNdQRDkCi4w5uyxp4Hh5FK0hyUh9LzObQuSuMvqYc+cW1OuI1b4G1RBNOwGOzxUeK+dPX6Q5Y96qcmOk5+eJyPOg2dtHaOujGvaW1MN/sVJPMy6xgCtJ6iSe9xDYYmxcha2quZK3LGGvW3d3/QznBqY+XwK6kbHXAgMBAAGjUDBOMEwGA1UdAQRFMEOAEP3fipkit68H++sodJuSZSWhHTAbMRkwFwYDVQQDExBjcm0ubGV2ZXJhdGUuY29tghAluuQuFlNJpU+Yh7Yf725TMAkGBSsOAwIdBQADgYEAZVECKrndJdjMYnfSb2bCByv24mpgE2yCuhm2Ey+cSEwP31aKrHIVNAcVDPd7k1/R4qsWU6I8PHjVCeCHTMnf+EE/1IV0lbCj/PD/D3by+m/7hEKdtzk6VHJyJLmLyO6fIJc14XPI4qC/KVuUS97UjNpWcICZFgM64Vb7MUW5thE=" />
        </identity>
      </endpoint>
      <endpoint address="https://localhost:8088/MyAppService" binding="wsHttpBinding"
        bindingConfiguration="MyAppServiceEndpointSSL" contract="MyCompanyMyAppService.IMyCompanyMyAppService"
        name="MyAppServiceEndpointSSL" />
      <endpoint address="https://localhost:8088/MyAppServiceBasic" binding="basicHttpBinding"
        bindingConfiguration="MyAppServiceEndpointBasicSSL" contract="MyCompanyMyAppService.IMyCompanyMyAppService"
        name="MyAppServiceEndpointBasicSSL" />
    </client>
    <bindings>
      <basicHttpBinding>
        <binding name="MyAppServiceEndpointBasicSSL" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport">
            <transport clientCredentialType="Basic" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <wsHttpBinding>
        <binding name="MyAppServiceEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
          receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
          transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="Certificate" negotiateServiceCredential="false"
              algorithmSuite="Default" establishSecurityContext="false" />
          </security>
        </binding>
        <binding name="MyAppServiceEndpointSSL" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="Certificate" negotiateServiceCredential="true"
              algorithmSuite="Default" establishSecurityContext="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>



  </system.serviceModel>

1 个答案:

答案 0 :(得分:1)

好吧,似乎目前没有解决方案;
WCF似乎只支持Windows凭据方法(参见here) 所以它又回到了绘图板......如果有人感兴趣 - this是我进入的方向。