Программный вызов WCF: проверка личности не удалась - PullRequest
0 голосов
/ 06 марта 2019

Я перехожу из App.config в программный режим для вызова службы WCF с аутентификацией / идентификацией сертификата клиента.Новый код - .NET Core, но целевой платформой приложения для тестовой консоли было установлено значение net472, чтобы оно работало в Azure Kudu.

Я искал везде, но не могу избавиться от этого сообщения об ошибке.

Ошибка:

Необработанное исключение: System.ServiceModel.Security.MessageSecurityException: проверка подлинности для исходящего сообщения завершилась неудачно.Ожидаемое удостоверение - это удостоверение (http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint)' для целевой конечной точки 'net.tcp: // myserver: 1001 / MyServiceRelay / MyServiceRelay.svc'.

Трассировка стека сервера: at System.ServiceModel.Security.*

<endpoint name="MyEndpoint"
                address="[PLACEHOLDER]"
                binding="netTcpBinding"
                bindingConfiguration="NetTcpAzureBinding"
                behaviorConfiguration="AzureCertificateBehavior"
                contract="MyCalledService">
        <identity>
          <certificate encodedValue="[PLACEHOLDER]" />
        </identity>
 </endpoint>

<netTcpBinding>
        <binding name="NetTcpAzureBinding" maxReceivedMessageSize="20485760">
          <readerQuotas maxArrayLength="20485760" maxStringContentLength="20485760" />
          <security mode="Message">
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
 </netTcpBinding>

<behavior name="AzureCertificateBehavior">
          <clientCredentials>
            <clientCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="[PLACEHOLDER]" />
            <serviceCertificate>
              <authentication certificateValidationMode="None" revocationMode="NoCheck" />
            </serviceCertificate>
          </clientCredentials>
 </behavior>

Эквивалент в коде:

// My FindCertificate method performs a lookup by thumbprint, exactly the same code that below when using "SetCertificate".
X509Certificate2 certificate = Common.FindCertificate(settings.CertificateThumbprint);
        var binding = new NetTcpBinding
        {
            // custom constant
            MaxReceivedMessageSize = Common.MaxReceivedMessageSize
        };
        // custom constant
        binding.ReaderQuotas.MaxArrayLength = Common.MaxArrayLength;
        // custom constant
        binding.ReaderQuotas.MaxStringContentLength = Common.MaxStringContentLength;

        binding.Security.Mode = SecurityMode.Message;
        binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

        var endpoint = new EndpointAddress(new Uri(settings.MailService.EndpointAddress), EndpointIdentity.CreateX509CertificateIdentity(certificate));

        _channelFactory = new ChannelFactory<IMailService>(binding, endpoint);

        _channelFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, settings.CertificateThumbprint);
        _channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
        _channelFactory.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;

Что не так? Спасибо за идеи.

1 Ответ

0 голосов
/ 06 марта 2019

Ну, ничего не было "неправильно", но сообщение об ошибке не удовлетворяло. Как только я получил его, мне просто нужно было заменить:

EndpointIdentity.CreateX509CertificateIdentity(certificate)

по:

EndpointIdentity.CreateDnsIdentity(settings.MailService.EndpointDns)

в инициализации идентификации конечной точки. И ожидаемое значение было в сообщении об ошибке ...

Что помогло мне, так это настроить фабрику каналов, которая инициализируется чтением классического файла .config в класс конфигурации:

        ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
        fileMap.ExeConfigFilename = "MailService.config";
        Configuration newConfiguration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

        _channelFactory = new ConfigurationChannelFactory<IMailService>("MyEndpoint", newConfiguration, new EndpointAddress("net.tcp://myserver:1001/MyServiceRelay/MyServiceRelay.svc"));

(ну, это не удалось вызвать конечную точку, просто дал подсказку).

Остается открытым вопрос: почему классическая конфигурация работала, не жалуясь на конечную точку DNS? Я проверил это снова. Я прочитал об этой проверке безопасности еще до 2010 года (предотвращает фишинг). Также полезно: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/service-identity-and-authentication

Комментарии приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...