[英]The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'
Few days ago I had quite a headache with authentication problems when using Windows authentication between client and wcf web service . 几天前, 在客户端和wcf Web服务之间使用Windows身份验证时,我对身份验证问题非常头疼。 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.
我得到的错误是“HTTP请求未经授权使用客户端身份验证方案'协商'。从服务器收到的身份验证头是”NTLM“。堆栈上的解决方案都没有工作,因为大多数解决方案都与旧方法有关。
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. 回答:问题是这个问题的所有帖子都与旧的kerberos和IIS问题有关,其中代理凭证或AllowNTLM属性有帮助。 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 provider under IIS Windows authentication providers list.
我从地面挑选蠕虫数小时后发现的是IIS安装程序列表中的某些IIS安装不包括协商提供程序。 So I had to add it and move up.
所以我不得不添加它并向上移动。 My WCF service started to authenticate as expected.
我的WCF服务开始按预期进行身份验证。 Here is the screenshot how it should look if you are using Windows authentication with Anonymous auth OFF .
下面是截图,如果您使用匿名身份验证关闭的Windows身份验证,它应该如何。
You need to right click on Windows authentication and choose providers menu item. 您需要右键单击Windows身份验证并选择提供程序菜单项。
Hope this helps to save some time. 希望这有助于节省一些时间。
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. Web.config:
<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. App.config:
<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>
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;
}
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 BackConnectionHostNames
registry key 如果您在同一台计算机上调用托管WCF服务时遇到此问题,则可能需要填充
BackConnectionHostNames
注册表项
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0
MSV1_0
, point to New, and then click Multi-String Value
. MSV1_0
,指向“新建”,然后单击“ Multi-String Value
。 BackConnectionHostNames
, and then press ENTER. BackConnectionHostNames
,然后按Enter。 BackConnectionHostNames
, and then click Modify. BackConnectionHostNames
,然后单击“修改”。 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. See Calling WCF service hosted in IIS on the same machine as client throws authentication error for details. 有关详细信息,请参阅在客户机所在的同一台计算机上调用IIS中托管的WCF服务 。
我的解决方案是将AppPool设置为使用AppPoolIdentity到NetworkService身份。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.