Проверка подлинности сообщения сертификата WCF x509 работает при построении в VS 2019, но не работает при самостоятельном размещении - PullRequest
0 голосов
/ 29 мая 2020

Я создал службу WCF и приложение простых форм для доступа к ней. До сих пор, до добавления сертификата, все работало отлично, и я смог успешно получить возврат от службы.

После экспериментов с сертификатами я смог обновить конфигурации в клиент и сервис, так что при создании из Visual Studio приложение отлично работает с сертификатами. канал не может быть открыт из-за сбоя согласования безопасности с конечной точкой. Это может быть связано с отсутствием или неправильным указанием EndpointIdentity в EndpointAddress, используемом для создания канала ». ошибка.

Просто интересно, может ли кто-нибудь увидеть какие-либо явные ошибки в моих конфигах, которые могут быть причиной этого? Как я уже сказал, это работает, когда визуальная студия монтирует службу, но что-то в собственном хостинге вызывает ошибку.

К вашему сведению: трассировка клиента просто говорит об ошибке, о которой я сказал выше. Трассировка сервера даже не отображается. 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();
        }
    }

1 Ответ

0 голосов
/ 29 мая 2020

Итак, после некоторого тестирования я обнаружил, что при создании собственного хоста он не извлекается из файла app.config службы WCF, поэтому вам придется в основном переписать его при создании хоста службы.

I ' я предоставил приведенный ниже код, который сработал для меня.

    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();
        }
    }
...