C# HTTP 请求未经授权,客户端身份验证方案为“协商”。从服务器收到的身份验证标头是“NTLM”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15570108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:13:19  来源:igfitidea点击:

The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'

c#windowswcfauthentication

提问by Vidas Vasiliauskas

Few days ago I had quite a headache with authentication problems when using Windows authentication between client and wcf web service. The error I was getting was "The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was "NTLM". None of the solutions on stack worked because most of them were related to old methods.

几天前,在客户端和 wcf Web 服务之间使用Windows 身份验证时,我对身份验证问题感到非常头疼。我得到的错误是“HTTP 请求未经客户端身份验证方案‘协商’授权。从服务器收到的身份验证标头是“NTLM”。堆栈上的解决方案都不起作用,因为它们中的大多数都与旧方法有关。

采纳答案by Vidas Vasiliauskas

THE ANSWER:The problem was all of the posts for such an issue were related to older kerberos and IIS issues where proxy credentials or AllowNTLM properties were helping. My case was different. What I have discovered after hours of picking worms from the ground was that somewhat IIS installation did not include Negotiate providerunder IIS Windows authentication providers list. So I had to add it and move up. My WCF service started to authenticate as expected. Here is the screenshot how it should look if you are using Windows authentication with Anonymous auth OFF.

答案:问题是针对此类问题的所有帖子都与较旧的 kerberos 和 IIS 问题有关,其中代理凭据或 AllowNTLM 属性有所帮助。我的情况不同。经过数小时从地下挑选蠕虫病毒后,我发现有些 IIS 安装不包括IIS Windows 身份验证提供程序列表下的协商提供程序。所以我不得不添加它并向上移动。我的 WCF 服务开始按预期进行身份验证。这是屏幕截图,如果您在使用匿名身份验证关闭的情况下使用 Windows 身份验证,它应该是什么样子。

You need to right click on Windows authentication and choose providers menu item.

您需要右键单击 Windows 身份验证并选择提供程序菜单项。

enter image description here

在此处输入图片说明

Hope this helps to save some time.

希望这有助于节省一些时间。

回答by Tom

The solution for me was to set the AppPool from using the AppPoolIdentity to the NetworkService identity.

我的解决方案是将 AppPool 从使用 AppPoolIdentity 设置为 NetworkService 标识。

回答by Ajay Shankar

I have upgraded my older version of WCF to WCF 4 with below changes, hope you can also make the similar changes.

我已将旧版本的 WCF 升级到 WCF 4,并进行了以下更改,希望您也可以进行类似的更改。

1. Web.config:

1. 网页配置:

<system.serviceModel>
      <bindings>
        <basicHttpBinding>
          <binding name="Demo_BasicHttp">
            <security mode="TransportCredentialOnly">
              <transport clientCredentialType="InheritedFromHost"/>
            </security>
          </binding>
        </basicHttpBinding>
      </bindings>
      <services>
        <service name="DemoServices.CalculatorService.ServiceImplementation.CalculatorService" behaviorConfiguration="Demo_ServiceBehavior">
          <endpoint address="" binding="basicHttpBinding"
              bindingConfiguration="Demo_BasicHttp" contract="DemoServices.CalculatorService.ServiceContracts.ICalculatorServiceContract">
            <identity>
              <dns value="localhost"/>
            </identity>
          </endpoint>
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="Demo_ServiceBehavior">
            <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
            <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
            <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
            <serviceDebug includeExceptionDetailInFaults="false"/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
      <protocolMapping>
        <add scheme="http" binding="basicHttpBinding" bindingConfiguration="Demo_BasicHttp"/>
      </protocolMapping>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>

2. App.config:

2. 应用配置:

    <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ICalculatorServiceContract" maxBufferSize="2147483647" maxBufferPoolSize="33554432" maxReceivedMessageSize="2147483647" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="4096" />
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:24357/CalculatorService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICalculatorServiceContract" contract="ICalculatorServiceContract" name="Demo_BasicHttp" />
    </client>
  </system.serviceModel>

回答by Sander Postma

For me the solution was besides using "Ntlm" as credential type:

对我来说,解决方案除了使用“Ntlm”作为凭证类型之外:

    XxxSoapClient xxxClient = new XxxSoapClient();
    ApplyCredentials(userName, password, xxxClient.ClientCredentials);

    private static void ApplyCredentials(string userName, string password, ClientCredentials clientCredentials)
    {
        clientCredentials.UserName.UserName = userName;
        clientCredentials.UserName.Password = password;
        clientCredentials.Windows.ClientCredential.UserName = userName;
        clientCredentials.Windows.ClientCredential.Password = password;
        clientCredentials.Windows.AllowNtlm = true;
        clientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
    }  

回答by fiat

Not this exact problem, but this is the top result when googling for almost the exact same error:

不是这个确切的问题,但这是谷歌搜索几乎完全相同的错误时的最佳结果:

If you see this problem calling a WCF Service hosted on the same machine, you may need to populate the BackConnectionHostNamesregistry key

如果您在调用同一台计算机上托管的 WCF 服务时看到此问题,则可能需要填充BackConnectionHostNames注册表项

  1. In regedit, locate and then click the following registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
  2. Right-click MSV1_0, point to New, and then click Multi-String Value.
  3. In the Name column, type BackConnectionHostNames, and then press ENTER.
  4. Right-click BackConnectionHostNames, and then click Modify. In the Value data box, type the CNAME or the DNS alias, that is used for the local shares on the computer, and then click OK.
    • Type each host name on a separate line.
  1. 在 regedit 中,找到并单击以下注册表子项: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
  2. 右键单击MSV1_0,指向新建,然后单击Multi-String Value
  3. 在“名称”列中,键入BackConnectionHostNames,然后按 Enter。
  4. 右键单击BackConnectionHostNames,然后单击修改。在“数值数据”框中,键入用于计算机上本地共享的 CNAME 或 DNS 别名,然后单击“确定”。
    • 在单独的行中键入每个主机名。

See Calling WCF service hosted in IIS on the same machine as client throws authentication errorfor details.

有关详细信息,请参阅在客户端引发身份验证错误的同一台计算机上调用托管在 IIS 中的 WCF 服务

回答by aliyan

I had the same problem, to solve it set specific user from domain in iis -> action sidebar->Basic Settings -> Connect as... -> specific user

我遇到了同样的问题,要解决它,请在 iis 中从域设置特定用户 -> 操作侧栏 -> 基本设置 -> 连接为... -> 特定用户

enter image description here

在此处输入图片说明