简单的 WCF SSL Web 服务

Posted

技术标签:

【中文标题】简单的 WCF SSL Web 服务【英文标题】:Simple WCF SSL Web Service 【发布时间】:2013-01-08 21:11:09 【问题描述】:

我正在我的机器上创建一个 WCF Web 服务,这是此框中的第一个此类服务。 我已经在我的机器上运行了一个 .NET 2.0 企业应用程序,运行许多 SOA SSL 服务。

我有一个内部 SSL 服务器授权,它为我的计算机创建了 SSL x509 证书。我还有许多由同一证书颁发机构创建的用于测试的客户端证书。所有这些证书都适用于我当前的应用程序。

我正在编写一个 WCF SSL Web 服务来接受纯 XML 消息,现在,为每个请求吐出每个存在的 HTTPHeader。

我在设置时遇到了一些问题。我可以在没有 SSL 的情况下找到它。

当我使用 WCF 服务 (https) 时,它会下载并创建对象并正常修改 app.config,它还会提示我有关服务器证书的信息。但是,当我向该 WCF 服务发送消息时,它会出错。

我机器上的服务 URL:

   https://8KZVJS1/HeaderIntercept/HeaderIntercept.svc 

当我尝试提交消息时,我开始收到错误:

HTTP 请求被客户端身份验证方案“匿名”禁止。

我尝试修改我的 app.config 但现在我只得到:

提供的 URI 方案“https”无效;预期的“http”。 参数名称:通过

更新:做了一些编辑,我现在得到: https://8kzvjs1/headerintercept/HeaderIntercept.svc 上没有可以接受消息的端点侦听。这通常是由不正确的地址或 SOAP 操作引起的。有关详细信息,请参阅 InnerException(如果存在)。

我需要通过一个简单的 .NET 客户端来完成这项工作,然后推送它,以便我们可以使用 Apache 反向代理将原始 SOAP 消息传递给它。

有什么想法吗?

Windows 7 - 64 位。

IIS

SSL - 不需要,但可以接受

匿名访问 - 已启用。

配置编辑器 - system.webServer/security/access SSl、SSLNegotiateCert、SSL128 检查

WCF 网络服务 web.config

  <system.serviceModel>        
    <bindings>    
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security>
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
  </bindings>
    <services>
      <service name="HeaderIntercept">           
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="WCFServiceCertificate.IService1" />
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior>
                      <serviceMetadata httpsGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
              <clientCertificate>
                <authentication certificateValidationMode="PeerTrust"/>
              </clientCertificate>
              <serviceCertificate findValue="8KZVJS1" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>

  </system.webServer>

客户端 app.config

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="52428800"  maxReceivedMessageSize="65536000" >
          <security mode="Transport">
            <transport clientCredentialType="Certificate" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>

      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://8KZVJS1/HeaderIntercept/HeaderIntercept.svc"
          binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
          contract="HeaderIntercept.IHeaderIntercept" name="wsHttpEndpointBinding">
        <identity>
          <dns value="8KZVJS1"/>
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>

IHeaderIntercept.cs

[ServiceContract]
public interface IHeaderIntercept


    [OperationContract]
    XElement MCCI_IN200100BC(XElement xml);


HeaderIntercept.svc

namespace WCF_Header_Intercept

    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
    public class HeaderIntercept : IHeaderIntercept
    
        public XElement MCCI_IN200100BC(XElement xml)
        
            StringBuilder sb = new StringBuilder();

            WebHeaderCollection headers = WebOperationContext.Current.IncomingRequest.Headers;
            foreach (string key in headers.Keys) 
                sb.AppendLine("header " + key + "=" + headers[key]);
            

            OperationContext.Current.IncomingMessageHeaders.AsParallel().ForAll(h => sb.AppendFormat("Name=0, IsReferenceParameter=1, MustUnderstand=2, Namespace=3, Relay=4, Actor=5.6", h.Name, h.IsReferenceParameter, h.MustUnderstand, h.Namespace, h.Relay, h.Actor, Environment.NewLine));

            System.Diagnostics.Debug.Write(sb.ToString());
            return XElement.Parse("<data>" + sb.ToString() + "</data>");
             
    

【问题讨论】:

This might 对你有用。顺便说一句,您的服务器配置和客户端配置似乎不兼容,因为客户端使用的是 HTTPS(transport 安全性),但服务器不是。您是自动(通过添加服务参考)还是手动创建客户端配置? 我有点想可能是这种情况,因为当我手动执行此操作时,它会在客户端执行 basicHttpBinding,因此我已手动完成。我会检查一下。有什么让你印象深刻的吗? 与论坛网站不同,我们不使用“谢谢”、“感谢任何帮助”或Stack Overflow 上的签名。请参阅“Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?. 我想礼貌不是约翰的要求;)真的,对某事保持欣赏、礼貌和诚实通常是我们试图传授给人们的品质。而不是冷漠、技术性和分析性。 【参考方案1】:

想通了。与我的合同匹配时,我的 web.config 绑定错误。我删除了命名空间以使事情变得更简单,并让它工作。

感谢托马斯的洞察力。希望我可以将其标记为答案:\

web.config:

 <system.serviceModel>
    <services>
      <service name="HeaderIntercept" >
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="IHeaderIntercept">
          <identity>
            <dns value="CGI-8KZVJS1"/>            
          </identity>
        </endpoint>

      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security mode="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- Add the following element to your service behavior configuration. -->
          <serviceMetadata httpsGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

app.config

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
          <binding name="WSHttpBinding_IHeaderIntercept" >
            <security mode="Transport">
              <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
              <message clientCredentialType="Certificate" algorithmSuite="Default" />
            </security>
          </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://cgi-8kzvjs1/HeaderIntercept/HeaderIntercept.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IHeaderIntercept"
            contract="HeaderIntercept.IHeaderIntercept" name="WSHttpBinding_IHeaderIntercept">
            <identity>
                <servicePrincipalName value="host/CGI-8KZVJS1" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

【讨论】:

以上是关于简单的 WCF SSL Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

WCF服务最简单的安全方法是啥

WCF 4 Web 服务中的 UsernameToken 和 SSL - 但使用 basicHttpBinding

要求 SSL 证书和客户端证书在 WCF JSON 服务中引发异常

基于 SSL 的 WCF - 404 错误

如何让 WCF 服务在 SSL 上运行?

使用ssl和客户端证书的Wcf:请求svc succes wcf调用返回403.16