C# 使用SOAP服务和IIS的Windows身份验证失败

C# 使用SOAP服务和IIS的Windows身份验证失败,c#,asp.net,web-services,soap,windows-authentication,C#,Asp.net,Web Services,Soap,Windows Authentication,我有一个客户端,它向SOAP服务发送一个简单的web请求。它是一个简单的C#程序,使用服务的WSDL文件创建客户机。该服务托管在IIS 8.5和Windows Server 2012上。它在使用匿名身份验证时工作正常,但在使用Windows身份验证时失败。客户端和服务都在同一个域中,用户权限也可以 我将IIS配置为禁用除Windows身份验证(协商、NTLM)之外的所有形式的身份验证。客户端已配置为使用Windows作为客户端凭据类型 当我发送请求时,会出现以下错误: HTTP请求未经客户端身份

我有一个客户端,它向SOAP服务发送一个简单的web请求。它是一个简单的C#程序,使用服务的WSDL文件创建客户机。该服务托管在IIS 8.5和Windows Server 2012上。它在使用匿名身份验证时工作正常,但在使用Windows身份验证时失败。客户端和服务都在同一个域中,用户权限也可以

我将IIS配置为禁用除Windows身份验证(协商、NTLM)之外的所有形式的身份验证。客户端已配置为使用Windows作为客户端凭据类型

当我发送请求时,会出现以下错误: HTTP请求未经客户端身份验证方案“协商”授权。从服务器收到的身份验证标头为“协商,NTLM”

然后我尝试了一个在github上找到的工具,名为“WebServicesStudio”。使用该工具,我设置了WSDL,选择了我的请求方法,即使使用Windows身份验证,它也能工作

我查看了Wireshark的两次尝试,并注意到WebServicesStudio请求在第一次请求中立即发送协商令牌,而我自己的客户端在第二次请求中发送令牌,据我所知,这就是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>
Web服务管理器:

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身份验证工作正常

你能提供你的客户端源代码吗?@OguzOzgul我编辑了这篇文章,将客户端源代码包括在内。你能检查一下clientCredentialType属性吗。将其设置为Ntlm可能会有所帮助。@OguzOzgul不幸的是,这也没有起作用。服务器也有类似的响应,但没有成功。我很抱歉对此进行了警告。是否可以共享服务端点?
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;
}