【问题标题】:Windows authentication with SOAP service and IIS failing使用 SOAP 服务和 IIS 的 Windows 身份验证失败
【发布时间】:2020-07-12 03:04:46
【问题描述】:

我有一个向 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");
        }
    }

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

【问题讨论】:

  • 能否提供您的客户端源代码?
  • @OguzOzgul 我编辑了帖子以包含客户端源代码。
  • 您能否检查一下clientCredentialType属性here。将其设置为 Ntlm 可能会有所帮助。
  • @OguzOzgul 不幸的是,这也没有成功。来自服务器的类似响应,但未成功。
  • 很抱歉加热它。是否可以共享服务端点?

标签: c# asp.net web-services soap windows-authentication


【解决方案1】:

所以看起来模拟设置不正确。在创建客户端对象之后,我在客户端程序中添加了以下行:

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

    return client;
}

现在 Windows 身份验证按预期工作!

【讨论】:

    猜你喜欢
    • 2012-09-23
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多