使用MSXML拒绝访问

时间:2009-07-29 13:34:17

标签: web-services vb6 msxml

我有一个经典ASP网站的VB6后端。然后,VB使用MSXML2.XMLHTTP在同一服务器上调用Web服务。这适用于我们所有的服务器但只有一个。如果我将Web服务站点设置为接受匿名登录,则它将起作用,但是如果我仅强制集成安全性,MSXML将返回“拒绝访问”错误。

我正在使用示例here.

中的代码
Set objDom = CreateObject("MSXML2.DOMDocument")
Set objXmlHttp = CreateObject("MSXML2.XMLHTTP")

' Load XML
objDom.async = False
objDom.loadXML XmlBody

' Open the webservice
objXmlHttp.Open "POST", AsmxUrl, False

' Create headings
objXmlHttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
objXmlHttp.setRequestHeader "SOAPAction", SoapActionUrl

' Send XML command
objXmlHttp.send objDom.xml

编辑: 按照AnthonyWJones的建议,我按照清单进行了检查,但仍然没有工作。使用Fiddler,它显示一个具有401响应的请求。身份验证选项卡显示:

No Proxy-Authenticate Header is present.
WWW-Authenticate Header is present: Negotiate
WWW-Authenticate Header is present: NTLM

我确实注意到了一种奇怪的行为。当我使用登录到远程桌面的用户的凭据来呼叫网站时,它将起作用。我得到谈判,挑战,然后200,它会工作。当用户通过远程桌面登录而不是其他时间登录时,有什么想法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

我猜你是依靠底层的WinINET HTTP堆栈在服务器使用Windows集成安全性挑战时向服务器提供当前用户凭据。

如果WinINET认为主机服务器位于Intranet区域,则默认情况下只会这样做。即便如此,可能已经调整了用户Intranet区域安全设置以禁止此操作。

尝试以与VB6 app运行的用户相同的用户身份使用浏览器从客户端计算机访问该站点。它认为服务器在哪个区域?如果不是Intranet,则需要将主机添加到属于该区域的站点列表中。您在那里打开区域安全设置并向下滚动到用户身份验证类别。登录应配置为“仅在Intranet区域中自动登录”。

修改:根据您的评论,这些内容配置正确。我想做的几件事就是: -

  1. 检查服务器是否严格配置为仅接受Windows集成安全性。
  2. 检查机器上的代理设置,权限是否被代理服务器拒绝?
  3. 使用ProgID“MSXML2.XMLHTTP.3.0”确保正在使用正确版本的MSXML dll(某些其他第三方应用程序的安装可能会损坏注册表,从而导致使用旧版本的MSXML)。 / LI>
  4. 在机器上安装Fiddler并在VB6应用程序尝试呼叫时观看http对话。是否有单一的401响应? WinINET是不是使用用户凭据?有3 401个回复吗? WinINET已尝试使用当前用户凭据,但服务器不接受它们。
  5. 这一点我们进入系统管理区域。例如,如果fiddler跟踪显示authenticat尝试未使用NTLM然后使用Kerberos身份验证,请检查服务器和客户端是否在5分钟内设置了时钟和域控制器。

    检查服务器事件日志,服务器无法联系域控制器。

    在只有Windows集成安全性的服务器上放置一个简单的.htm并尝试从浏览器中点击它,这是否成功?

答案 1 :(得分:3)

回复Ryan可能为时已晚,但其他人可能会遇到同样的问题,所以我会发布这个问题:我有一个开发人员遇到与MSXML2.XMLHTTP相同的问题。问题是我有样本从回来做这个,所以我知道使用工作,但它现在不...可能是最近引入的错误?我们依靠WinINET堆栈自动检测本地Intranet,然后堆栈愿意做Windows集成。该站点位于代理绕过列表中,默认选项将其放入本地Intranet。事实上,当您浏览到该站点并转到“安全设置”选项卡时,您会看到“本地Intranet”已突出显示,因此它似乎正在运行。但是,MSXML2.XMLHTTP仍然不愿意进行Windows集成...除非您使用“安全”选项卡上的“站点/高级”按钮直接将站点添加到本地Intranet。

所以我的结论是,现在WinINET堆栈中存在某种错误,它将自动检测到的本地Intranet站点视为与直接添加到站点列表中的站点不同。有趣的是,当浏览到网站时,事情就像希望的那样工作,并且自动使用Windows集成(即使没有直接添加到网站):它只是 编程访问通过MSXML2.XMLHTTP不起作用。

最后,这不是我们结束的事情:我们使用的是MSXML2.ServerXMLHTTP.6.0。这个堆栈(WinHTTP)似乎把事情做对了,但是,有一点需要注意:它默认不使用IE的代理设置,所以你有一些选择 - 使用ProxyCfg(适用于XP及更早版本)或NETSH适用于Vista和稍后在WinHTTP堆栈中导入IE代理设置。缺点是每个客户端计算机上的额外配置(这是一个胖客户端VB应用程序)。我们选择做的是将以下内容放在Send:

之前

HTTP.SetProxy 2,“myproxy.mydomain.com”,“* .mydomain.com”

由于您将访问mydomain站点,您可能会认为可以改为说HTTP.SetProxy 0来绕过代理,但这不起作用。必须告诉堆栈:“我有一个代理,但绕过它为我的域名,顺便说一句,我要去的网站是在该域名中,因此它是本地Intranet”。

答案 2 :(得分:0)

在查看AnthonyWJones建议的所有内容之后,我发现我可以通过以下方式使用基本身份验证:

 objXmlHttp.Open "POST", AsmxUrl, False, UserName, Password

如果我允许集成安全性,它会尝试协商但是然后失败并且401,但如果只允许基本身份验证它将连接。这不是我的第一选择,但它比允许匿名访问更好的解决方法。如果有人可以解释如何获得集成的安全性工作,我会将这个开放一段时间保持开放状态,然后给AnthonyWJones提供接受的答案,因为他的清单很好并且让我找到了另一个选项。

Fiddler非常乐于帮助我找到这一切。