Проверка подлинности NTLM клиента WCF возвращает 500 - PullRequest
0 голосов
/ 08 июля 2020

У меня проблема с подключением приложения WinForms к службе WCF с использованием проверки подлинности NTLM.

Оригинальное приложение было написано мной в 2005 году как мой первый код C#. С небольшими доработками все получилось. Веб-сервис был asmx с DataSets. Недавно пришло время обновить его из-за: проблем с производительностью и обновления Windows 10 на клиенте (требовалось обновление Crystal Reports 10.5.37 до x64, а официальная загрузка среды выполнения на сайте SAP не предусмотрена). Я переписал его с помощью WCF,. NET 4.8, заменив Crystal библиотекой для создания файлов Excel. В среде разработчика новая версия работает хорошо, кроме кода 500. Остальное и. NET Ядро не рассматривалось (слишком сложно объяснить; не по техническим причинам).

Когда пользователь запустил новую версию, первой непосредственной проблемой было «Доступ запрещен». Потом запустили от имени администратора. Код ошибки: «Не удалось запустить приложение из-за неправильной параллельной конфигурации». Затем я безуспешно пытался получить дополнительную информацию в средстве просмотра событий: информации не было. Инструмент sxstrace поднял доступ запрещен. Через несколько дней я получил это: я оставил комментарий в файле конфигурации, содержащий символы sh не на английском языке. После удаления комментария во время подключения произошла ошибка 500.

<\ LongStory-optional>

Приложение вызывает службу Verify, которая просто возвращает постоянное значение 1.

Сообщение об ошибке: «Тип содержимого text / html ответного сообщения не соответствует типу содержимого привязки (text / xml; charset = utf-8).

При использовании пользовательский кодировщик, убедитесь, что метод IsContentTypeSupported реализован правильно. Первые 75 байтов ответа были:

Страница не может быть отображена из-за внутренней ошибки сервера ». . Https не использовался.

Странно то, что после открытия .sv c один раз в IE ошибка исчезла до перезагрузки рабочей станции. Это доказывает, что клиент и сервер работают правильно. В то же время в старом приложении такой проблемы нет. По этой причине я попытался использовать «Веб-ссылку» вместо «Ссылка на службу». Похоже, что «Веб-ссылка» работает правильно. Дальше я пробовал разные настройки на стороне клиента. Я обнаружил, что "Service reference" работает после этого изменения: client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

С помощью инструмента fiddler я обнаружил, что обмен сообщениями почти такой же, за исключением конечного результата: до изменения у меня есть статусы 401/401 / 500, после изменения 401/401/200, другие отличия - время и значение NTLM base64, ничего больше.

Я думаю, что это не решение, а только обходной путь. Знаете ли вы, как правильно обрабатывать NTLM-аутентификацию с помощью WCF?

Важнейшие части моего кода и конфигурации:

var client = new ServiceClient();
client.ClientCredentials.Windows.ClientCredential.UserName = Dialog1.textBox1.Text;
client.ClientCredentials.Windows.ClientCredential.Domain = Dialog1.textBox2.Text;
client.ClientCredentials.Windows.ClientCredential.Password = Dialog1.textBox3.Text;
try
{
    i = client.Verify().Status;
} ...         

   

Конфигурация:

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding name="basicEndpoint" sendTimeout="infinite"  >
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Ntlm"/>
        </security>
      </binding>
    </basicHttpBinding>
  </bindings>
  <client>
    <endpoint address="http://wro67zt2/AlsbWebServices/WindService/WindService.svc" binding="basicHttpBinding" bindingConfiguration="basicEndpoint" contract="WindService.IService" name="basicEndpoint"/>
  </client>
</system.serviceModel>

Я считаю этот сервер боковая конфигурация не требуется. Он хорошо работает с веб-ссылкой, поэтому я могу предположить, что здесь все в порядке. Я пробовал «Windows» вместо «Ntlm», но проблема осталась прежней, он меняет строку NTLM на Negotiate в сообщениях запроса / ответа, а также количество сообщений с 3 до 2 (401/500 или 401/200).

Edit - конфигурация сервера:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2"/>
    <globalization culture="en-GB" requestEncoding="utf-8" responseEncoding="utf-8"/>
    <pages controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID"/>
    <identity impersonate="false" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicBinding" >
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"  realm="XXXXX"/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <services>
      <service behaviorConfiguration="WindService.Behavior" name="WindLibrary.Service">
        <endpoint 
          address="" 
          binding="basicHttpBinding"
          bindingConfiguration="basicBinding"
          name="basicEndpoint" 
          bindingNamespace="http://XXXXX.com/services/prime/"
          contract="WindLibrary.IService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WindService.Behavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
            <add scheme="http" binding="basicHttpBinding" bindingConfiguration="HttpBinding" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="false"/>
  </system.webServer>
</configuration>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...