#c# #wcf #wcf-binding #wcf-security
#c# #wcf #wcf-привязка #wcf-безопасность
Вопрос:
Я перехожу из App.config в программный, чтобы вызвать службу WCF с аутентификацией / удостоверением сертификата клиента. Новый код — .NET Core, но целевой фреймворк тестового консольного приложения был установлен на net472, чтобы он запускался в Azure Kudu.
Я искал везде, но не могу избавиться от этого сообщения об ошибке.
Ошибка:
Необработанное исключение: Система.ServiceModel.Безопасность.Исключение MessageSecurityException: ошибка проверки подлинности исходящего сообщения. Ожидаемая идентификация — ‘identity(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’.
Трассировка стека сервера: в системе.ServiceModel.Безопасность.IdentityVerifier.Обеспечьте идентификатор (EndpointAddress ServiceReference, AuthorizationContext AuthorizationContext, String errorString) в системе.ServiceModel.Безопасность.MessageSecurityProtocol.Обеспечить исходящую идентификацию (токен SecurityToken, средство аутентификации SecurityTokenAuthenticator)
App.config:
<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:
Ну, ничего не было «неправильно», но сообщение об ошибке не удовлетворило. Как только я получил это, мне просто пришлось заменить:
EndpointIdentity.CreateX509CertificateIdentity(certificate)
Автор::
EndpointIdentity.CreateDnsIdentity(settings.MailService.EndpointDns)
при инициализации идентификации конечной точки. И ожидаемое значение было в сообщении об ошибке…
Что помогло мне, так это настроить фабрику каналов, которая инициализируется чтением файла classical .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://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/service-identity-and-authentication
Комментарии приветствуются.