在VS 2019中构建的WCF x509证书消息认证可以使用,但自带托管功能时却失效了。

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

我已经创建了一个WCF服务和一个简单的表单应用程序来访问它。到目前为止,在添加证书之前,所有的工作都很完美,我能够成功地从服务中得到一个返回。

在试验了证书之后,我已经能够更新客户端和服务中的配置,这样当从visual studio中构建时,应用程序使用证书就能完美地工作。

我的问题是,当我使用一个自托管控制台应用程序来托管visual studio以外的服务时,我得到一个 "安全通道无法打开,因为与端点的安全协商已经失败。这可能是由于在用于创建通道的EndpointAddress中没有或不正确指定EndpointIdentity。"错误。

只是想知道是否有人能看到我的配置中有任何明显的错误,可能会导致这种情况?就像我说的那样,当visual studio挂载服务时,它可以工作,但自我托管中的某些东西会导致错误。

顺便说一下:客户端跟踪只是说我上面说的错误。服务器跟踪甚至没有出现。WCFTestClient也说服务正在被托管。

干杯!

客户端。

<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
                 switchValue="Information, ActivityTracing"
                 propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData="c:\Client.svclog"  />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    <system.serviceModel>
      <behaviors>
        <endpointBehaviors>
          <behavior name="endpointCredentialsBehavior">
            <clientCredentials>
              <clientCertificate findValue="TraceCert"
                                 storeLocation="LocalMachine"
                                 x509FindType="FindBySubjectName"/>
            </clientCredentials>
          </behavior>
        </endpointBehaviors>
      </behaviors>
        <bindings>
            <wsHttpBinding>
                <binding name="clientBinding">
                    <security>
                        <message clientCredentialType="Certificate" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8000/ContactTraceWCF" binding="wsHttpBinding"
                bindingConfiguration="clientBinding" contract="ContactTraceServer.IContactTraceServer"
                name="WSHttpBinding_IContactTraceWCF" behaviorConfiguration="endpointCredentialsBehavior">
                <identity>
                    <dns value="TraceRootCA" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

服务器:

<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
                 switchValue="Information, ActivityTracing"
                 propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\Server.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  <system.serviceModel>
    <services>
      <service name="ContactTraceWCF.ContactTraceServer">
        <endpoint address="" 
                  binding="wsHttpBinding" 
                  bindingConfiguration="WSHttpBinding_IContactTraceWCF"
                  contract="ContactTraceWCF.IContactTraceServer"
                  name="WSHttpBinding_IContactTraceWCF">
          <identity>
            <dns value="TraceRootCA" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/ContactTraceWCF" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True" />
          <serviceCredentials>
            <serviceCertificate findValue="TraceRootCA"
                                storeLocation="CurrentUser"
                                x509FindType="FindBySubjectName"/>
            <clientCertificate>
              <authentication certificateValidationMode="None"/>
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IContactTraceWCF">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

托管控制台应用程序。

    using (ServiceHost serviceHost = new ServiceHost(typeof(ContactTraceServer), new Uri("http://localhost:8000/ContactTraceWCF")))
    {
        try
        {
            serviceHost.AddServiceEndpoint(typeof(IContactTraceServer), new WSHttpBinding(), "");

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            serviceHost.Description.Behaviors.Add(smb);
            serviceHost.Open();

            Console.WriteLine("The service is ready.");
            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.ReadLine();
            serviceHost.Close();
        }
        catch (TimeoutException timeProblem)
        {
            Console.WriteLine(timeProblem.Message);
            Console.ReadLine();
        }
        catch (CommunicationException commProblem)
        {
            Console.WriteLine(commProblem.Message);
            Console.ReadLine();
        }
    }
c# wcf x509certificate self-hosting
1个回答
0
投票

所以经过一些测试,我发现在创建自主机的时候,它并没有从WCF服务的app.config中提取,所以在构建servicehost的时候,你基本上必须重写它。

我提供了下面的代码,对我来说是可行的。

    using (ServiceHost serviceHost = new ServiceHost(typeof(ContactTraceServer), new Uri("http://localhost:8000/")))
    {
        try
        {
            var binding = new WSHttpBinding();
            binding.Security.Mode = SecurityMode.Message;
            binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
            serviceHost.AddServiceEndpoint(typeof(IContactTraceServer), binding, "ContactTraceWCF");
            serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "TraceRootCA");
            serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            serviceHost.Description.Behaviors.Add(smb);
            serviceHost.Open();


            Console.WriteLine("The service is ready.");
            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.ReadLine();
            serviceHost.Close();
        }
        catch (TimeoutException timeProblem)
        {
            Console.WriteLine(timeProblem.Message);
            Console.ReadLine();
        }
        catch (CommunicationException commProblem)
        {
            Console.WriteLine(commProblem.Message);
            Console.ReadLine();
        } catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.ReadLine();
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.