HTTP请求未经客户端身份验证方案“Ntlm”的授权。

17

当我调用Web服务时,我遇到了以下错误:

HTTP请求未获授权,客户端身份验证方案为“NTLM”。从服务器接收到的身份验证标头为“NTLM”。HTTP请求未获授权,客户端身份验证方案为“NTLM”。从服务器接收到的身份验证标头为“NTLM”。

我有一个Silverlight 4应用程序,调用位于我IIS(7)上的WCF Web服务。 我的WCF Web服务使用NTLM(Windows身份验证)调用安装在不同Web服务器上的另一个ASMX Web服务。 我的服务器和托管ASMX Web服务的服务器都在同一个域中。

当Silverlight客户端使用http://localhost/MySiteName从服务器打开应用程序时,一切正常。但是当Silverlight客户端从不是服务器但仍在同一个域中的不同客户端使用http://MyServerName/MySiteName打开应用程序时,则会出现错误。

我的IIS启用了Windows身份验证。 我的IIS禁用了匿名身份验证。

调用我的WCF Web服务的绑定配置为:

    <binding name="winAuthBasicHttpBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" />
      </security>
    </binding>

调用 ASMX Web 服务的绑定配置如下:

    <binding name="ClNtlmBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Ntlm" />
      </security>
    </binding>

调用我的WCF Web服务的绑定配置是:      <binding name ="winAuthBasicHttpBinding">        <security mode ="TransportCredentialOnly">          <transport clientCredentialType ="Windows" />        </security>      </binding> 调用ASMX Web服务的绑定配置是:      <binding name ="ClNtlmBinding">        <security mode ="TransportCredentialOnly">          <transport clientCredentialType ="Ntlm" />        </security>      </binding> - kruvi
7个回答

20

好的,以下是我想到的事情:

  • 您的 WCF 服务(假定在 IIS 上运行)必须在具有调用 Web 服务的特权的安全上下文下运行。您需要确保应用程序池使用的是域用户 - 最好是专用用户。
  • 您不能使用模拟来使用用户的安全令牌通过模拟传递回 ASMX,因为我的 WCF Web 服务调用另一个安装在**不同**Web 服务器上的 ASMX Web 服务
  • 尝试将Ntlm更改为Windows,然后再测试。

好的,简单介绍一下模拟。 基本上,众所周知,您无法使用您从一个服务器获得的模拟令牌将其传递到另一台服务器。原因似乎是令牌是使用用户密码生成的哈希值,并且针对生成它的计算机有效,因此无法从中间服务器使用。


更新

委托在 WCF 下是可能的(即从一个服务器向另一个服务器转发模拟)。请查看此主题here


当我将域用户设置为应用程序池时,它运行良好,但现在所有对WS的调用都是在应用程序池域用户下执行的。 我不能使用模拟来调用ASMX ws吗?这样调用就会在客户端用户安全令牌下执行。 - kruvi
顺便提一下,当使用模拟登录特定用户(与客户端登录的用户相同)时,一切都运行良好:client = new ClCustomersServiceClient(); client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("username", "password", "domain");
response = client.ClCustomersQuery(request);
- kruvi
1
你正在使用WCF服务器上的用户名和密码来模拟ASMX服务器。虽然这是可能的,但你不能传递用于访问WCF的Windows身份验证,以访问ASMX。 - Aliostad

8

对于我来说,解决方案是除了使用类似于Jeroen K的解决方案中提到的“NTLM”凭据类型之外。如果我有权限级别,我会在他的帖子上加分,但让我在这里发布我的整个代码,它将支持Windows和其他凭据类型,如基本认证:

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

8
自从这个问题发布以来已经过了很长时间,但我在类似情况下遇到了同样的问题。我有一个控制台应用程序,正在使用 Web 服务,我们的 IIS 服务器(Web 服务所在位置)启用了 Windows 身份验证(NTLM)。
我按照此链接中的步骤解决了我的问题。以下是App.config的示例代码:
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="Service1Soap">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Ntlm" proxyCredentialType="None"
                        realm=""/>
                    <message clientCredentialType="UserName" algorithmSuite="Default"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost/servicename/service1.asmx" 
            binding="basicHttpBinding" bindingConfiguration="ListsSoap"/>
    </client>
</system.serviceModel>

5
我不得不从以下内容移动域名、用户名和密码:

client.ClientCredentials.UserName.UserName = domain + "\\" + username; client.ClientCredentials.UserName.Password = password

到以下内容:

client.ClientCredentials.Windows.ClientCredential.UserName = username; client.ClientCredentials.Windows.ClientCredential.Password = password; client.ClientCredentials.Windows.ClientCredential.Domain = domain;


1
这对我也起作用,我使用了一个 SSRS asmx 服务来为 .NetCore 项目提供支持。 - Azhar

0
我的问题是:非管理员用户在访问我的asmx服务时会收到“http请求未经授权,客户端验证方案为'negotiate'”的错误提示。
我已经给了非管理员用户读取/执行文件夹的权限,这样问题就解决了。

0

也许你可以参考一下:http://msdn.microsoft.com/en-us/library/ms731364.aspx 我的解决方案是将authenticationScheme和proxyAuthenticationScheme这两个属性改为"Ntlm",然后它就可以工作了。

PS:我的环境如下: - 服务器端:.net 2.0 ASMX - 客户端:.net 4


0

1) 我必须对我的配置进行以下操作:(添加BackConnectionHostNames或禁用Loopback Check)http://support.microsoft.com/kb/896861

2) 我在一个隔离的开发网络上使用开发系统进行工作。我已经通过在URL中使用开发系统的计算机名称使其正常工作,但是当我将URL修改为将在生产中使用的URL时(而不是计算机名称),我开始遇到NTLM错误。

3) 我注意到安全日志显示服务帐户无法登录,并出现与MSDN文章中类似的错误。

4) 添加BackConnectionHostNames后,我可以通过在服务器上运行的浏览器登录服务器,但是服务帐户在尝试为Web服务进行身份验证时仍然出现NTLM错误。最后,我禁用了回环检查,问题得到解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接