Windows аутентификация с сервисом SOAP и сбой IIS - PullRequest
2 голосов
/ 31 марта 2020

У меня есть клиент, который отправляет простой веб-запрос в службу SOAP. Это простая C# программа, использующая файл WSDL службы для создания клиента. Служба размещена на IIS 8.5 и Windows Server 2012. Она отлично работает при использовании анонимной аутентификации, но не работает с Windows аутентификацией. И клиент, и служба находятся в одном домене, с правами пользователя тоже все в порядке.

Я настроил IIS так, чтобы он отключал все формы проверки подлинности, кроме Windows (Negotiate, NTLM). Клиент настроен так, что он использует Windows в качестве типа учетных данных клиента.

Когда я отправляю запрос, я получаю следующую ошибку: "HTTP-запрос не авторизован с помощью схемы проверки подлинности клиента« Согласование » Заголовок аутентификации, полученный от сервера, был 'Negotiate, NTLM' "

. Затем я попробовал инструмент, найденный на github, под названием " WebServiceStudio ". С помощью этого инструмента я установил WSDL, выбрал метод запроса, и он работал, даже с аутентификацией Windows.

Я просмотрел обе попытки с помощью Wireshark и заметил, что запрос WebServiceStudio немедленно отправляет токен Negotiate с первым запрос, в то время как мой собственный клиент отправляет токен во втором запросе, который, насколько я понимаю, обычно работает Windows аутентификация.

Я пробовал на стороне IIS, но пока ничего не получалось:

  • Изменен порядок проверки подлинности (согласование, NTLM и NTLM, согласование)
  • Изменена проверка подлинности только на согласование
  • Изменена расширенная защита в расширенных настройках (ни один из вариантов не имел значения )
  • Проверено, что оба модуля WindowsAuthentication и WindowsAuthenticationModule были установлены

Моя цель заключается в том, чтобы мой собственный клиент C# мог успешно пройти аутентификацию с Windows аутентификацией.

Вот конфигурация C# клиента:

<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <system.serviceModel>
    <client>
      <endpoint address="server address" binding="basicHttpBinding"
          bindingConfiguration="MyContractSoap" contract="MyContract.MyContractSoap" />
    </client>
    <bindings>
      <basicHttpBinding>
        <binding name="MyContractSoap">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" proxyCredentialType="Windows" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

А вот данные wireshark по запросу моего клиента:

POST /ABC/ShipmentDocuments.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "ABC/DocumentShipped"
Host: sdespte3
Content-Length: 333
Expect: 100-continue
Accept-Encoding: gzip, deflate

<!-- Server rejects request and states authentication method -->
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Tue, 18 Feb 2020 10:20:01 GMT
Content-Length: 1344

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Nicht autorisiert: Zugriff aufgrund ung.ltiger Anmeldeinformationen verweigert.</title>
</head>
<body>
<div id="header"><h1>Serverfehler</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>401 - Nicht autorisiert: Zugriff aufgrund ung.ltiger Anmeldeinformationen verweigert.</h2>
  <h3>Die angegebenen Anmeldeinformationen berechtigen Sie nicht, dieses Verzeichnis oder diese Seite anzuzeigen.</h3>
 </fieldset></div>
</div>
</body>
</html>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body>Request data here</s:Body></s:Envelope>

<!-- We send the negotiate token -->
POST /ABC/ShipmentDocuments.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "ABC/DocumentShipped"
Accept-Encoding: gzip, deflate
Authorization: Negotiate YIIHog...Token here
Host: abc
Content-Length: 333
Expect: 100-continue

<!-- Rejected again, unsure why -->
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Tue, 18 Feb 2020 10:20:01 GMT
Content-Length: 1344

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Nicht autorisiert: Zugriff aufgrund ung.ltiger Anmeldeinformationen verweigert.</title>
<style type="text/css">

И, наконец, данные wireshark другого работающего инструмента:

POST /ABC/ShipmentDocuments.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "ABC/DocumentShipped"
Authorization: Negotiate YIILV...Token here
Host: sdespiis1
Content-Length: 415
Expect: 100-continue

HTTP/1.1 100 Continue

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>Request body here</soap:Body></soap:Envelope>

<!-- Accepted -->
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
Persistent-Auth: false
X-Powered-By: ASP.NET
WWW-Authenticate: Negotiate oYG2MIGzo... Token here
Date: Tue, 18 Feb 2020 15:24:39 GMT
Content-Length: 295

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>Body here</soap:Body></soap:Envelope>

Обновление: Вот исходный код клиента для вызова службы.

Программа:

class Program
    {
        static void Main(string[] args)
        {
            sendWebRequest();
        }


        static int _orderId = 1;
        static int _mandant = 1;
        static string _sId = "0123456789012345678901";
        static string _isShipped = "eingeliefert";

        static void sendWebRequest()
        {
            Console.WriteLine("Start webrequest Orderid: {0}, mandant: {1}, sId: {2}, isShipped: {3}", _orderId, _mandant, _sId, _isShipped);
            WebserviceManager wm = new WebserviceManager();
            wm.Open();
            wm.SetStateToShipped(_orderId, _mandant, _sId, _isShipped);
            wm.Close();
            Console.WriteLine("Webrequest erfolgreich");
        }
    }

WebserviceManager:

public class WebserviceManager
    {
        protected MyContract.MyContractSoapClient _soapClient;

        public WebserviceManager()
        {
        }

        public void Open() 
        {
            _soapClient = createWebServiceClient();
            try
            {
                _soapClient.Open();
            }
            catch (Exception ex)
            {
                Logging.Error("Open", ex);
                throw ex;
            }

            Logging.Info("_soap-Client open");

        }

        public void Close()
        {
            _soapClient.Close();
        }

        public void SetStateToShipped(int orderNo, int mandant, string sId, string isShipped)
        {
            _soapClient.DocumentShipped(orderNo, mandant, sId, isShipped);
        }

        protected MyContract.MyContractSoapClient createWebServiceClient()
        {            
            return new MyContract.MyContractSoapSoapClient();
        }
    }

1 Ответ

0 голосов
/ 06 апреля 2020

Похоже, что олицетворение не было правильно настроено. Я добавил следующую строку в свою клиентскую программу сразу после создания объекта клиента:

protected MyContract.MyContractSoapClient createWebServiceClient()
{            
    var client = new MyContract.MyContractSoapSoapClient();
    client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

    return client;
}

И теперь Windows аутентификация работает как положено!

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