模拟和 CredentialCache.DefaultCredentials 给出 HTTP 401 Unauthorized

发布于 2024-07-16 18:54:59 字数 1263 浏览 6 评论 0原文

我有一个 ASMX Web 服务(在我的本地主机 - WinXP IIS 5.1 上),我从 Web 客户端调用它。 我的 Web 服务必须使用另一个 ASMX Web 服务(在 Win 2003 服务器 IIS 6.0 上)。

当我以“硬编码”方式在 Web 服务代码中提供凭据时:

engineWSE.Credentials = new System.Net.NetworkCredential("myUser", "myPass", "myDomain");

...远程 Web 服务的后续调用工作正常

现在我正在尝试在一些初步测试中冒充自己。 我对此的初步阅读告诉我这可能是一个大主题,但这是我为初学者所做的:

  1. 在我的中未选中“匿名访问” WebClient 的虚拟目录 我的本地主机上的站点

  2. 在我的Web客户端站点的web.config中,我建立了:身份验证模式=“Windows”和身份模拟=“true”

  3. 在必须调用远程服务的 Web 服务的 Web 方法中, 我改为:

    engineWSE.Credentials = System.Net.CredentialCache.DefaultCredentials; 
      
  4. 当使用这些调用远程 Web 服务时 默认凭据,我得到 以下错误:

    系统.Web.服务 System.Web.Services.Protocols.SoapException:服务器无法处理请求。--->

    System.Net.WebException:请求失败,HTTP 状态 401:未经授权。

    位于 System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse (SoapClientMessage 消息、WebResponse 响应、Stream responseStream、布尔 asyncCall)

    at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[]parameters)

我不确定我是否误解并试图过度简化“模拟” ” 或者远程 Web 服务是否以某种方式连接为仅接受具有 3 个参数(即用户名、密码、域)的凭据。

I have an ASMX web service (on my localhost - WinXP IIS 5.1) that I call from a webclient. My webservice must consume another ASMX web service (on a Win 2003 server IIS 6.0).

When I provide credentials in my webservice code in a "hard-coded" manner:

engineWSE.Credentials = new System.Net.NetworkCredential("myUser", "myPass", "myDomain");

...the subsequent invoke of the remote web service works fine.

Now I am trying to impersonate myself in some initial testing. My initial reading on this tells me this can be a big subject but here is what I've done for starters:

  1. UNCHECKED "Anonymous access" in my
    virtual directory for the WebClient
    site on my localhost

  2. in web.config of my webclient site, I established: authentication mode="Windows" and identity impersonate="true"

  3. in the webmethod of my webservice that has to call the remote service,
    I changed to:

    engineWSE.Credentials = System.Net.CredentialCache.DefaultCredentials;
    
  4. When the remote webservice gets invoked with these
    DefaultCredentials, I get the
    following error:

    System.Web.Services
    System.Web.Services.Protocols.SoapException: Server was unable to process request.--->

    System.Net.WebException: The request failed with HTTP status 401: Unauthorized.

    at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse
    (SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)

    at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

I am not sure whether I have misunderstood and tried to over-simplify "Impersonation" or whether the remote webservice is somehow wired to only accept credentials with 3 arguments (i.e. username, password, domain).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤蝉 2024-07-23 18:54:59

正如@Michael Levy 所说,这是一个双跳问题。 这意味着,除非您配置 Kerberos(协商),否则 NTLM 可能在运行 IIS 的 Windows 环境中使用,在计算机 A 上使用浏览器的客户端尝试访问计算机 B 上的网站将可以访问该站点,但是,当此站点将尝试联系计算机 C 上的服务,应改用池凭据。

对于网站 A 调用服务 B,服务 B 又调用服务 C 也是如此。

为网站配置 Kerberos 时,应考虑多种因素。 首先是要知道它是否是一个农场。 如果是,您必须为场中所有计算机的池定义一个公共用户。 这是必需的,因为 Kerberos 使用域名来标识用于加密安全令牌的主体。如果同一场的不同计算机上有不同的用户,因为它们都将通过相同的域名进行访问,所以所有请求都将搜索相同的条目。 可以在此处找到更多详细信息 Kerberos 和负载平衡

例如,假设您有一个 URL 为 myApp.intranet 的站点。 在 AD 中,您可以将 SPN 设置为域 MyDomain 中的 myUser (setspn -S MyDomain\myUser HTTP/myapp.intranet)。 当请求发送到 KDN(有关 KDN 的更多信息,请参阅末尾的 kerberos 链接)时,它将始终返回使用 myUser 加密的令牌,但 IIS 将尝试使用不同的用户对其进行解密。 为同一服务 (HTTP/myapp.intranet) 创建多个 SPN 可能很诱人,但这会使 KRB 出错。

另外,如果您使用的是 IIS 7+,如果您想保持内核模式身份验证处于启用状态(强烈建议这样做),则必须在 ApplicationHost.config 中设置一些详细信息: useAppPoolCredentials=true。 该值必须在configuration\system.webServer\security\authentication\windowsAuthentication 上设置。 这是因为默认情况下, 内核模式身份验证将使用计算机帐户,而不是池帐户,这将使我们回到多用户场景。

在所有情况下,信任此用户..必须启用 AD 主体的“委派”选项卡才能使委派工作。 然后,您必须决定是否要使用一般委派或约束委派。

正如我之前所说,您还必须为正确的用户和正确的服务设置 SPN。 用户很容易识别,因为它将是您在池中定义的用户,但根据您的配置,该服务可能会变得有点棘手。 DNS、浏览器和可能的其他变量可能会改变应该使用的内容。 我们的试验和错误显示了以下情况:

  • 如果您的 DNS 条目是 A 条目,则可以直接使用它
  • 如果您的条目是 CName,在我们的测试中,它使用与其关联的 A 条目
  • 我们曾经遇到过 CName 为用过,好像和浏览器版本有关。

请注意,如果没有专门设置 SPN 并且您通过 NetBIOS 名称访问网站,则将请求 HTTP/machine 服务,并且默认情况下 主机服务(搜索额外) 可以用来代替 HTTP,因此主机/机器将使用。 这对于在小型网络上轻松配置非常有用。

还要记住,如果您想限制从 NTLM 到 Kerberos 时的停机时间,您应该首先修改 ApplicationHost,然后使用 SetSPN。 您还可以在执行任何操作之前禁用协商,并仅保留 NTLM,直到一切设置完毕,然后,如果可能,仅启用协商(不使用 NTLM)。 这应该迫使客户改变他们访问您网站的方式。 如果不这样做,缓存机制似乎会在 NTLM 上保留一段时间。

希望这能有所帮助。 如果您在配置 Kerberos 时仍然遇到问题,WireShark 是您最忠实的朋友。 您可以在以下页面中找到有关如何调试 Kerberos 的信息:
- 为网站调试 Kerberos
- 调试 AD Kerberos 问题(最大令牌大小就是其中之一)
- Kerberos 工具和其他链接
- 一般网络捕获 Kerberos调试

As @Michael Levy said, this is a double hop problem. What this means is that unless you configure Kerberos (Negotiate), NTLM is probably used in a windows environment running IIS, having a client with a browser on machine A trying to access website on machine B will have access to the site BUT, when this site will try to contact service on machine C, the pool credentials should be used instead.

The same is true for website A calling service B which in turn calls service C.

When configuring Kerberos for websites, multiple things should be accounted for. The first is to know if it is a farm or not. If it is, you must define a common user for the Pool for all machines part of the farm. This is required because Kerberos uses the domain name to identify the principal used to encrypt the security tokens.If you had different users on different machines of the same farm, since they would all be accessed through the same domain name, all requests would search for the same entry. More detailed information may be found here on Kerberos and load balancing.

For instance, say you have a site with myApp.intranet as a URL. In AD, you would have an SPN set to, say, myUser in domain MyDomain (setspn -S MyDomain\myUser HTTP/myapp.intranet). When the request is sent to the KDN (see kerberos links at the end for mor info on KDN), it will always return a token encrypted with myUser but IIS will try to decrypt it with different users. It may be tempting to create multiple SPN for a same service (HTTP/myapp.intranet) but this would make KRB error out.

Also, if you are on IIS 7+, you will have to set a little detail in your ApplicationHost.config if you want to keep Kernel-mode authentication enabled (which is strongly recommended): useAppPoolCredentials=true. This value must be set on configuration\system.webServer\security\authentication\windowsAuthentication. This is because by default, Kernel-mode auth will use the Computer account, not the pool account and this would bring us back to the multi-user scenario.

In all cases, the Trust this user for ... of the Delegation tab of the AD principal must be enabled for delegation to work. You then have to decide if you want to use general or constrained delegation.

As I said earlier, you also have to set a SPN for the right user and the right service. The user is quite easy to identify sinc it will be the one you defined on your pool but the service may get a little tricky depending on your configuration. DNS, browser and probably other variables may change what should be used. Our trials and errors have shown the following:

  • If your DNS entry is an A entry, you use it directly
  • If your entry is a CName, in our tests, it used the A entry associated with it
  • We have had cases where the CName would be used and it seemed to be related to the version of the browser.

Note that if no SPN is specifically set and that you access your website through the NetBIOS name, the HTTP/machine service will be requested and that by default, HOST service (search for extra) may be used in place of HTTP so HOST/machine would be used. This can be useful for easy configuration on a small network.

It is also to keep in mind that if you want to limit downtime when going from NTLM to Kerberos, you should first modify the ApplicationHost, then, use SetSPN. You can also disable negotiate befor any action and keep only NTLM until everything is set up and then, if possible, enable only negotiate (without NTLM). This should force clients to modify the way they access your website. If you don't do this, caching mechanism seems to tend to keep on NTLM for a while.

Hoping this can help. If you still have problem configuring Kerberos, WireShark is your most faithful friend. You can find information on how to debug Kerberos in the following pages:
- Debug Kerberos for a website
- Debug AD problems with Kerberos (max token size is one of them)
- Kerberos tools and other links
- General network capture Kerberos debugging

羅雙樹 2024-07-23 18:54:59

您是否使用netmon或wireshark来确保凭据通过? 服务提供商的日志告诉您什么? 另外,请确保 web.config(或其他 .config)中没有配置模拟标签。

编辑:

可能是 HostingEnvironment.Impersonate() 块 - 默认情况下使用应用程序池的身份,或者您传递给它的任何用户令牌的身份。

Have you used netmon or wireshark to make sure the credentials are getting passed? What's the log on the service provider telling you? Also, make sure there's no impersonation tag configured in web.config (or other .config).

EDIT:

A HostingEnvironment.Impersonate() block perhaps -- that utilizes the app pool's identity by default, or the identity of any user token you pass it.

春庭雪 2024-07-23 18:54:59

这是典型的双跳问题 - 除非在您的域中正确配置了 Kerberos 委派,否则您无法使用通过模拟获得的用户凭据来访问另一台服务器。 此问题重复

This is classic double-hop problem - you can't use user credential gained through impersonation to access another server unless Kerberos Delegation is properly configured in your domain. Duplicate of this question

嘦怹 2024-07-23 18:54:59

根据以下 MSDN 文章,不适用于 HTTP 和 FTP 协议。 当您连接到远程服务器时,您必须显式提供凭据。

According to the following MSDN article, it will not work for HTTP and FTP protcols. You will have to explicitly provide the credentials when you make a connection to the remote server.

埋葬我深情 2024-07-23 18:54:59

@ Michael Kniskern - 这对于 HTTP 来说当然是可能的。 模拟功能会将凭据从 ASP.Net 应用程序传递到 IIS。 通过集成 Windows 身份验证,将使用最终用户的凭据,而不是默认的 ASPNET 帐户(或附加到应用程序池的帐户)。 我相信 MSDN 文章中提到的 HTTP 和 FTP 是针对 DefaultNetworkCredentials 的。

@ Michael Kniskern - It is certainly possible with HTTP. The impersonate feature will pass the credentials from the ASP.Net app to IIS. With Integrated Windows Authentication, the end user's credentials will then be used instead of the default ASPNET account (or account attached to the App Pool). That MSDN article's mention to HTTP and FTP was directed at DefaultNetworkCredentials, I believe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文