从basicHttpBinding升级到wsHttpBinding:连接失败

时间:2010-06-27 18:38:54

标签: .net wcf security authentication

我维护一个在用户之间发送消息的程序。客户端连接到我的域服务器上的IIS 7.0中承载的WCF服务。到目前为止,我成功地使用了basicHttpBinding,没有任何配置。现在,我想更改为wsHttpBinding,因为这应该加密消息的传输。服务器安装了证书,但我没有做任何事情来使用WCF服务。我没有为wsHttpBinding配置任何选项。

现在,当我从域内的任何客户端连接到WCF服务时,该客户端由托管WCF服务的同一服务器管理所有很好。但是当我尝试从域外的客户端连接到服务时,连接失败。客户端获得一个异常,指出“调用者未通过服务进行身份验证”。所以它必须是身份验证问题。

我该如何解决这个问题?关于这个主题的一些有用资源的指针也非常受欢迎。

编辑: 所以这就是我如何运作的。希望它会让你们中的一些人头疼...

问题如下:

  • IIS托管了两个网站:mydomain.com和www.mydomain.com
  • 我想在www.mydomain.com上托管WCF服务,因为我购买了该网址的证书。
  • WCF抛出错误'此集合已包含带有方案http的地址。这个系列中每个方案最多只能有一个地址。在我身边。
  • 您必须通过添加baseAddressPrefixFilter
  • 来解决此问题
  • 我只想要传输安全性,没有用户身份验证

  • 在我解决了那个之后,我收到一个错误,指出:'提供的URI方案'https'无效;预期'http'
  • 此错误由客户端生成,而不是由服务器生成。

这是完成技巧的web.config:

<system.serviceModel>
     <serviceHostingEnvironment>
        <baseAddressPrefixFilters>
          <add prefix="http://www.mydomain.com"/>
        </baseAddressPrefixFilters>
     </serviceHostingEnvironment>

    <services>
      <service behaviorConfiguration="ServiceBehavior" name="MyApp.MyService">
        <endpoint address="mex"
                  binding="mexHttpsBinding"
          contract="IMetadataExchange"
           />
    <endpoint address="wsHttp"
          binding="wsHttpBinding"
                  bindingConfiguration="NoAuthentication"
                  contract="MyApp.IContract"/>
      </service>
    </services>
    <bindings>
    <wsHttpBinding>
        <binding name="NoAuthentication">
         <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
    </wsHttpBinding>
   </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

最后,但非常重要:我必须告诉客户端它应该使用transportsecurity模式,因为我没有使用svcutil创建客户端。

 public static IContract GetContract()
        {
            var binding = new WSHttpBinding(SecurityMode.Transport) {MaxReceivedMessageSize = 655350};
            var factory = new ChannelFactory<IContract>(
                          binding,
                          new EndpointAddress(@"https://www.mydomain.com/MyService.svc/wsHttp"));
            return factory.CreateChannel();
        }

1 个答案:

答案 0 :(得分:2)

这是预期的默认行为。默认情况下,WsHttpBinding将使用Windows凭据来验证您的呼叫者。这适用于您的域 - 但在其外部失败。

您需要做的是拥有第二个端点,该端点也使用wsHttpBinding,但安全设置不同,或者您需要将整个身份验证机制切换到域内外工作的东西 - 用户名/密码,例如:服务器端的ASP.NET成员资格系统,或者您需要在调用者的计算机上安装证书。

更新:最终引用将是WCF Security Guidance on Codeplex,其中包含有关如何在WCF中执行特定安全相关操作的大量操作方法和分步说明。< / p>