Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF使用证书跨计算机边界进行身份验证_C#_Wcf Security - Fatal编程技术网

C# WCF使用证书跨计算机边界进行身份验证

C# WCF使用证书跨计算机边界进行身份验证,c#,wcf-security,C#,Wcf Security,我编写了一些示例代码,试图让WCF客户端在请求/应答场景中与WCF服务器(不在IIS中托管)通信。但我需要使用证书进行身份验证,而不是用户名/密码。当计算机具有相同的用户名和密码时,我的测试工作正常,但当我将密码更改为不同密码时,测试失败 我尝试过几种不同的想法,但都没有奏效。有人能告诉我我做错了什么吗 以下是我的示例代码: WCF请求-应答库(Service1.cs): 接口合同(IService1.cs): 测试应用程序(可以是服务器和客户端,Hoster.cs) 使用系统; 使用Syste

我编写了一些示例代码,试图让WCF客户端在请求/应答场景中与WCF服务器(不在IIS中托管)通信。但我需要使用证书进行身份验证,而不是用户名/密码。当计算机具有相同的用户名和密码时,我的测试工作正常,但当我将密码更改为不同密码时,测试失败

我尝试过几种不同的想法,但都没有奏效。有人能告诉我我做错了什么吗

以下是我的示例代码: WCF请求-应答库(Service1.cs):

接口合同(IService1.cs):

测试应用程序(可以是服务器和客户端,Hoster.cs)

使用系统;
使用System.ServiceModel;
使用系统线程;
使用System.Windows.Forms;
使用Test2ServLib;
命名空间Test2HostApp
{
公共部分课程主持人:表格
{
公共招待员()
{
初始化组件();
textBox1.Text=Environment.MachineName;
}
私有void StartServer_单击(对象发送方,事件参数e)
{
ThreadPool.QueueUserWorkItem(runHost);
}
私有静态bool-bRunning=false;
私有静态对象锁定器=新对象();
私有静态字符串proto=“https”;//System.Net.WebException:基础连接已关闭:发送时发生意外错误。-->System.IO.IOException:无法从传输连接读取数据:现有连接被远程主机强制关闭。-->System.Net.Sockets.SocketException:现有连接被远程主机强制关闭奥斯特


我需要做什么才能使这些解决方案中的一个(或两个)正常工作?

旁注,我使用“makecert.exe-sr CurrentUser-ss my-a sha1-n CN=WCFServer-sky exchange-pe”创建了我的证书并根据需要复制它们。如果我需要以其他方式创建证书,请让我知道。这是概念验证代码,因此自签名对我有效。您是否使用WsHttp进行服务绑定,然后使用netTcp进行客户端代码?可能是
using System;
namespace Test2ServLib
{
    public class Service1 : IService1
    {
        public CompositeTypeRsp GetDataUsingDataContract(CompositeTypeReq composite)
        {
            CompositeTypeRsp Rsp = new CompositeTypeRsp();
            if (composite == null)
            {
                Rsp.Value = "Hello {null} from " + Environment.MachineName;
                return Rsp;
            }
            Rsp.Value = "Hello " + composite.Value + " from " + Environment.MachineName;
            return Rsp;
        }
    }
}
using System;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace Test2ServLib
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        CompositeTypeRsp GetDataUsingDataContract(CompositeTypeReq composite);
    }

    [DataContract]
    public class CompositeTypeReq
    {
        string stringValue = "Hello ";
        [DataMember]
        public string Value
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
    [DataContract]
    public class CompositeTypeRsp
    {
        string stringValue = "Hello ";
        [DataMember]
        public string Value
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
}
using System;
using System.ServiceModel;
using System.Threading;
using System.Windows.Forms;
using Test2ServLib;

namespace Test2HostApp
{
    public partial class Hoster : Form
    {
        public Hoster()
        {
            InitializeComponent();
            textBox1.Text = Environment.MachineName;
        }

        private void StartServer_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(runHost);
        }
        private static bool bRunning = false;
        private static object locker = new object();
        private static string proto = "https";// <-- this line changes between tests
        private void runHost(object state)
        {
            lock (locker)
            {
                if (bRunning)
                {
                    MessageBox.Show("Host already running");
                    return;
                }
                bRunning = true;
            }
            Uri baseAddress = new Uri($"{proto}://localhost:2202/Test2ServLib/Service1/");
            WSHttpBinding binding = new WSHttpBinding();
//            binding.Security.Mode = SecurityMode.Transport;
//            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
            try
            {
                using (ServiceHost host = new ServiceHost(typeof(Service1), baseAddress))
                {
                    host.Open();
                    MessageBox.Show("Host started");
                    while (bRunning == true)
                    {
                        Thread.Sleep(100);
                    }
                    host.Close();
                    MessageBox.Show("Host stopped");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"{ex}");
            }
        }

        private void StopServer_Click(object sender, EventArgs e)
        {
            lock (locker)
            {
                bRunning = false;
                Thread.Sleep(100); // wait for the host to close
            }
        }

        private void ClientReq_Click(object sender, EventArgs e)
        {
            try
            {
                Uri baseAddress = new Uri($"{proto}://{textBox1.Text}:2202/Test2ServLib/Service1/");
                EndpointAddress address = new EndpointAddress(baseAddress);
                ChannelFactory<IService1> factory =
                            new ChannelFactory<IService1>("Test2ServLib.IService1", address); 
                var patientSvc = factory.CreateChannel();
                var rsp = patientSvc.GetDataUsingDataContract(new CompositeTypeReq { Value = "me" } );
                MessageBox.Show(rsp.Value);
            }
            catch(Exception ex)
            {
                MessageBox.Show($"error-{ex}");
            }
        }
    }
}
namespace Test2HostApp
{
    partial class Hoster
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be     disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {    
            this.btnStart = new System.Windows.Forms.Button();
            this.btnStop = new System.Windows.Forms.Button();
            this.btnSend = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.btnStart.Location = new System.Drawing.Point(12, 12);
            this.btnStart.Name = "btn_Start";
            this.btnStart.Size = new System.Drawing.Size(75, 23);
            this.btnStart.TabIndex = 0;
            this.btnStart.Text = "Start";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.StartServer_Click);
            // 
            // button2
            // 
            this.btnStop.Location = new System.Drawing.Point(12, 41);
            this.btnStop.Name = "btn_Stop";
            this.btnStop.Size = new System.Drawing.Size(75, 23);
            this.btnStop.TabIndex = 1;
            this.btnStop.Text = "Stop";
            this.btnStop.UseVisualStyleBackColor = true;
            this.btnStop.Click += new System.EventHandler(this.StopServer_Click);
            // 
            // button3
            // 
            this.btnSend.Location = new System.Drawing.Point(12, 70);
            this.btnSend.Name = "btn_Send";
            this.btnSend.Size = new System.Drawing.Size(75, 23);
            this.btnSend.TabIndex = 2;
            this.btnSend.Text = "Send";
            this.btnSend.UseVisualStyleBackColor = true;
            this.btnSend.Click += new System.EventHandler(this.ClientReq_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(93, 70);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 22);
            this.textBox1.TabIndex = 3;
            // 
            // Hoster
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(282, 255);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.btnSend);
            this.Controls.Add(this.btnStop);
            this.Controls.Add(this.btnStart);
            this.Name = "Hoster";
            this.Text = "Hoster";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btnStart;
        private System.Windows.Forms.Button btnStop;
        private System.Windows.Forms.Button btnSend;
        private System.Windows.Forms.TextBox textBox1;
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="announcementBehavior" 
               name="Test2ServLib.Service1">
        <endpoint binding="netTcpBinding" 
                  bindingConfiguration="RequestReplyNetTcpBinding"
                  contract="Test2ServLib.IService1" />
        <host>
        </host>
      </service>
    </services>
    <client>
      <endpoint binding="netTcpBinding" 
                bindingConfiguration="StandardNetTcpBinding" 
                contract="Test2ServLib.IService1" 
                name="Test2ServLib.IService1" 
                behaviorConfiguration="LargeEndpointBehavior">
      </endpoint>
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="announcementBehavior">
          <!--The following behavior attribute is required to enable WCF serialization of large data sets -->
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
          <serviceDiscovery>
            <announcementEndpoints>
              <endpoint kind="announcementEndpoint"
                        address="net.tcp://localhost:8005/Announcement"
                        binding="netTcpBinding"
                        bindingConfiguration="RequestReplyNetTcpBinding"/>
            </announcementEndpoints>
          </serviceDiscovery>
          <serviceThrottling maxConcurrentCalls="1500"
                             maxConcurrentSessions="1500"
                             maxConcurrentInstances="1500"/>
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
            <serviceCertificate findValue="WCfServer"
                                storeLocation="CurrentUser"
                                storeName="My"
                                x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>

        <behavior name="discoveryBehavior">
          <serviceDiscovery>
          </serviceDiscovery>
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
            <serviceCertificate findValue="WCfServer"
                                storeLocation="CurrentUser"
                                storeName="My"
                                x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="LargeEndpointBehavior">
          <!--The behavior is required to enable WCF deserialization of large data sets -->
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
          <clientCredentials>
            <clientCertificate findValue="WcfClient" 
                               x509FindType="FindBySubjectName"
                               storeLocation="CurrentUser" 
                               storeName="My" />
            <serviceCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding  name="StandardNetTcpBinding"
                 receiveTimeout="05:00:00"
                 openTimeout="00:00:59"
                 closeTimeout="00:00:59"
                 maxBufferPoolSize="524288"
                 maxBufferSize="25000000"
                 maxConnections="50"
                 maxReceivedMessageSize="25000000"
                 listenBacklog="1500"
                 sendTimeout="00:05:00">
          <security>
            <message clientCredentialType="Certificate"/>
          </security>

          <reliableSession ordered="false" 
                           inactivityTimeout="00:01:00" 
                           enabled="true" />
          <readerQuotas maxDepth="2147483647" 
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647" 
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
        </binding>
        <binding  name="RequestReplyNetTcpBinding"
                 receiveTimeout="05:00:00"
                 openTimeout="00:00:59"
                 closeTimeout="00:00:59"
                 maxBufferPoolSize="524288"
                 maxBufferSize="25000000"
                 maxConnections="50"
                 maxReceivedMessageSize="25000000"
                 sendTimeout="00:05:00"
                 listenBacklog="1500">
          <reliableSession ordered="false" 
                           inactivityTimeout="00:01:00" 
                           enabled="true" />
          <readerQuotas maxDepth="2147483647" 
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647" 
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
          <security >
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
       <wsHttpBinding>
        <binding name="CertificateWithTransport" messageEncoding="Mtom">
         <security mode="TransportWithMessageCredential">
           <transport clientCredentialType="None" />
           <message clientCredentialType="Certificate" />
         </security>
        </binding>
        <binding name="CertificateWithTransportService" messageEncoding="Mtom" >
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" />
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="Test2ServLib.Service1"
               behaviorConfiguration="credentialConfigService" >
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="CertificateWithTransportService"
                  contract="Test2ServLib.IService1" />
      </service>
    </services>
    <client>
      <endpoint address=""
                behaviorConfiguration="credentialConfigurationClient"
                binding="wsHttpBinding"
                bindingConfiguration="CertificateWithTransport"
                contract="Test2ServLib.IService1"
                name="Test2ServLib.IService1" />
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="credentialConfigService">
           <serviceCredentials>
             <clientCertificate>
               <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" />
             </clientCertificate>
           </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="credentialConfigurationClient">
          <clientCredentials>
            <clientCertificate findValue="WCfServer"
                                storeLocation="CurrentUser"
                                storeName="My"
                                x509FindType="FindBySubjectName" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>