如何在wcf中的netHttpBinding中设置HTTPS?

问题描述 投票:0回答:1

我必须创建一个示例项目,其中客户端和服务器通过 https(wss) 与 netHttpBinding 进行通信。我的代码和配置与 http 绑定工作得非常好。但是当我使用 HTTPS 时,它会给出如下错误

System.ServiceModel.CommunicationException:“向 https://localhost:8080/NetHttp 发出 HTTP 请求时发生错误。这可能是由于在 HTTPS 情况下未使用 HTTP.SYS 正确配置服务器证书。这也可能是由于客户端和服务器之间的安全绑定不匹配造成的。'

代码及配置如下

  1. IHTTPService.cs(服务合约)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace NetHttpBindingPocSvc
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract(CallbackContract = typeof(IDuplexServiceCallBack))]
    public interface IHttpService
    {

        [OperationContract]
        void SendMessage(string message);
    }

    public interface IDuplexServiceCallBack
    {
        [OperationContract]
        void ReceiveMessage(string message);
    }
}
  1. 服务实施
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class HttpService : IHttpService
    {
        public void SendMessage(string message)
        {
            Console.WriteLine($"Message from client received: {message}");

            var callback = OperationContext.Current.GetCallbackChannel<IDuplexServiceCallBack>();
            if (callback != null)
            {
                callback.ReceiveMessage("Message has been received");
            }
        }
  1. 服务托管
 internal class Program
 {
     static void Main(string[] args)
     {
         var serviceInstance = new ServiceHost(typeof(NetHttpBindingPocSvc.HttpService));
         serviceInstance.Open();
         Console.WriteLine($"Service is up and running");
         Console.ReadLine();
     }
 }
  1. 应用程序配置(服务器)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
    </startup>
    <system.serviceModel>
        <protocolMapping>
            <add scheme="http" binding="netHttpBinding" />
            <add scheme="https" binding="netHttpsBinding" />
        </protocolMapping>
        <services>
            <service name="NetHttpBindingPocSvc.HttpService" behaviorConfiguration="netHttpBindingBehaviour">
                <endpoint address="" binding="netHttpBinding" contract="NetHttpBindingPocSvc.IHttpService" bindingConfiguration="netHttpBinding">
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="https://localhost:8080/NetHttp" />
                        <add baseAddress="http://localhost:8081/NetHttp"/>
                    </baseAddresses>
                </host>
            </service>
        </services>
        <bindings>
            <netHttpBinding>
                <binding name="netHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:40:00" sendTimeout="00:40:00"
                         transferMode="Buffered" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="20000000" maxBufferSize="2147483647"
                         maxReceivedMessageSize="2147483647">
                    <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="20000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:40:00" enabled="false" />
                    <security mode="Transport">
                        <transport clientCredentialType="None"></transport>
                    </security>
                </binding>
            </netHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="netHttpBindingBehaviour">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true" />
                    <serviceCredentials>
                        <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
                    </serviceCredentials>
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>
  1. 客户端代码(服务消费)
   internal class Program
{
    static void Main(string[] args)
    {

        var message = Console.ReadLine();
        string url = $"wss://localhost:8080/NetHttp";
        var instanceContext = new InstanceContext(new DuplexMessageReceiver());
        NetHttpService.HttpServiceClient client = new NetHttpService.HttpServiceClient(instanceContext);
        client.Endpoint.Address = new System.ServiceModel.EndpointAddress(new Uri(url), EndpointIdentity.CreateDnsIdentity("localhost"));
        //client.ClientCredentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "localhost");
        client.Open();
        client.SendMessage(message);
        Console.ReadLine();
    }
    public class DuplexMessageReceiver : NetHttpService.IHttpServiceCallback
    {
        public void ReceiveMessage(string message)
        {
            Console.WriteLine(message);
        }
    }
}
  1. 客户端配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
    </startup>
    <system.serviceModel>
        <bindings>
            <netHttpBinding>
                <binding name="NetHttpBinding_IHttpService">
                    <security mode="Transport">
                        <transport clientCredentialType="None" />
                    </security>
                    <webSocketSettings transportUsage="Always" />
                </binding>
            </netHttpBinding>
        </bindings>
        <client>
            <endpoint address="wss://localhost:8080/NetHttp" binding="netHttpBinding"
                bindingConfiguration="NetHttpBinding_IHttpService" contract="NetHttpService.IHttpService"
                name="NetHttpBinding_IHttpService" />
        </client>
    </system.serviceModel>
</configuration>

我不确定我在这件事上做错了什么。相同的证书配置对于 net.tcp 绑定工作正常

c# wcf
1个回答
0
投票

尝试在这里修改它:

<client>
            <endpoint address="wss://localhost:8080/NetHttp" binding="netHttpBinding"
                bindingConfiguration="NetHttpBinding_IHttpService" contract="NetHttpService.IHttpService"
                name="NetHttpBinding_IHttpService" />
<identity>
    <dns value="localhost" />
</identity>
        </client>

记得使用证书。

© www.soinside.com 2019 - 2024. All rights reserved.