簡體   English   中英

使用 SOAP 服務和 IIS 的 Windows 身份驗證失敗

[英]Windows authentication with SOAP service and IIS failing

我有一個客戶端向 SOAP 服務發送一個簡單的 Web 請求。 它是一個簡單的 C# 程序,它使用服務的 WSDL 文件來創建客戶端。 該服務托管在 IIS 8.5 和 Windows Server 2012 上。使用匿名身份驗證時它工作正常,但使用 Windows 身份驗證失敗。 客戶端和服務都在同一個域中,用戶權限也可以。

我配置了 IIS,以便它禁用除 Windows 身份驗證(協商、NTLM)之外的所有形式的身份驗證。 客戶端已配置為使用 Windows 作為客戶端憑據類型。

當我發送請求時,我收到以下錯誤: “HTTP 請求未經客戶端身份驗證方案‘協商’授權。從服務器收到的身份驗證標頭是‘協商,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");
        }
    }

網絡服務管理器:

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();
        }
    }

所以看起來模擬設置不正確。 在創建客戶端對象后,我在客戶端程序中添加了以下行:

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

    return client;
}

現在 Windows 身份驗證按預期工作!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM