Я создал консольное приложение C #, щелкнул правой кнопкой мыши по значку References в обозревателе решений и выбрал «Add Service Reference». Когда я ввожу адрес и нажимаю «Перейти», я получаю следующую ошибку:
Metadata contains a reference that cannot be resolved: 'https://MyWebAddress.com/MyService'.
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was ''.
The remote server returned an error: (401) Unauthorized.
If the service is defined in the current solution, try building the solution and adding the service reference again.
Предполагается, что веб-служба использует аутентификацию на основе сертификатов. У меня есть сертификат клиента, загруженный в мое хранилище личных ключей.
Когда я захожу в «Дополнительно»> «Добавить веб-ссылку» и затем вхожу в URL, мне предлагается выбрать сертификат. После выбора сертификата я получаю другую ошибку:
Value cannot be null.
Parameter name: discoveryError & mexError
До того, как администраторы сервера изменили безопасность на аутентификацию сертификата, я смог подключиться с помощью имени пользователя и пароля. Итак, у меня есть сервисные ссылки, созданные еще до того, как произошла смена безопасности. Но когда я пытаюсь соединиться с этим консольным приложением C # с веб-службой, я получаю следующую ошибку:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was ''.
Вот XML в моей конфигурации приложения:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBindingConfig" closeTimeout="00:01:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="655360000" maxBufferPoolSize="52428800" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384000" maxBytesPerRead="409600000" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://MyWebAddress.com/MyService" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfig" contract="MyService" name="MyServiceTest" />
</client>
</system.serviceModel>
Вот как я назначаю сертификат прокси. Функция GetCertificate взята из проприетарной библиотеки DLL, созданной системными администраторами в моей компании (веб-служба принадлежит другой компании).
Добавление сертификата в прокси:
[System.Security.SecuritySafeCritical]
protected void Initialize(string endpointName)
{
if (this.ClientCredentials != null)
{
var cert = MyCompany.CryptoHelper.GetCertificate(Settings.LocalCert_FriendlyName);
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls;
}
}
Когда я подключаюсь к веб-службе с помощью Internet Explorer, у меня запрашивают сертификат, выбирают его, а затем появляется следующая ошибка:
401 / No+client+certificate+chain+in+this+request