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

问题描述 投票:0回答:8

调用网络服务时出现以下错误:

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

我有一个调用 WCF Web 服务的 Silverlight 4 应用程序,两者都在我的 IIS 上 (7)。 我的 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>
c# .net windows silverlight wcf
8个回答
20
投票

好的,这是我想到的事情:

  • 假设在 IIS 上运行的 WCF 服务必须在具有调用 Web 服务的权限的安全上下文下运行。您需要确保应用程序池中的用户是域用户 - 最好是专用用户。
  • my WCF web service calls another ASMX web service, installed on a **different** web server
  • 起,您不能使用模拟来使用用户的安全令牌通过模拟传回 ASMX
  • 尝试将
    Ntlm
    更改为
    Windows
    并再次测试。

好的,关于模仿的几句话。 基本上,这是一个已知问题,您无法使用到达一台服务器的模拟令牌传递到另一台服务器。原因似乎是令牌是一种使用用户密码的哈希值,并且对生成的机器有效,因此不能从中间服务器使用它。


更新

在 WCF 下可以进行

委托(即将模拟从一台服务器转发到另一台服务器)。看看这个主题这里


8
投票

问题发布已经很长时间了,但我在类似的情况下遇到了同样的问题。我有一个控制台应用程序,并且正在使用一个 Web 服务,并且放置该 Web 服务的 IIS 服务器启用了 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>

8
投票

对我来说,解决方案除了使用“Ntlm”作为凭证类型之外,类似于 Jeroen K 的解决方案。如果我有权限级别,我会在他的帖子上加上,但让我在这里发布我的整个代码,它将支持 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;
    }  

5
投票

我必须从

移动域名、用户名、密码

client.ClientCredentials.UserName.UserName = 域名 + “\” + 用户名; client.ClientCredentials.UserName.Password = 密码

client.ClientCredentials.Windows.ClientCredential.UserName = 用户名; client.ClientCredentials.Windows.ClientCredential.Password = 密码; client.ClientCredentials.Windows.ClientCredential.Domain = 域;


0
投票

1)我必须对我的配置执行以下操作:(添加 BackConnectionHostNames 或禁用环回检查) http://support.microsoft.com/kb/896861

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

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

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


0
投票

也许你可以参考:http://msdn.microsoft.com/en-us/library/ms731364.aspx 我的解决方案是更改 2 个属性 authenticationScheme 和 proxyAuthenticationScheme 改为“Ntlm”,然后就可以了。

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


0
投票

我的问题是; 没有管理员用户在我的 asmx 服务上收到“http 请求未经客户端身份验证方案‘协商’asmx 的授权”。

我向非管理员用户授予了读取/执行文件夹权限,我的问题得到了解决。


0
投票

当我更改凭证时,它对我有用:

rsExec.ClientCredentials.UserName.UserName = userName;
rsExec.ClientCredentials.UserName.Password = password;

致:

rsExec.ClientCredentials.Windows.ClientCredential.UserName = userName;
rsExec.ClientCredentials.Windows.ClientCredential.Password = password;

HttpClientCredentialType 当然是 Ntlm

我希望这会有所帮助

© www.soinside.com 2019 - 2024. All rights reserved.