【问题标题】:HTTP Request Object and processing local requestsHTTP 请求对象和处理本地请求
【发布时间】:2009-10-23 07:47:20
【问题描述】:

我有一个使用 CDO Message 对象通过电子邮件发送报告的 Web 应用程序。

例如:

Dim objCDO
Set objCDO = Server.CreateObject("CDO.Message")
objCDO.CreateMHTMLBody "http://server/report.asp"

问题是当它向 IIS 发出请求时,它没有继承登录用户的 ASP 会话标识,即在允许访问内容之前用于验证请求的会话变量是空白的。这使得身份验证变得困难,迫使我添加一个查询字符串变量(因为如您所见,您不能向此请求添加表单变量),例如:

objCDO.CreateMHTMLBody "http://server/report.asp?userid=xx&password=xx"

报告中肯定有一种授权方式来检查请求是否来自本地机器,即邮件脚本中的CDO对象,从而否定身份验证的需要?

【问题讨论】:

  • @Jimbo:编辑了我的答案以解决您的评论。

标签: iis asp-classic httprequest cdo.message


【解决方案1】:

只是不要这样做!出于这些原因:-

  • 向服务器发出第二个请求将导致当前线程阻塞,如果您有太多这些请求,则会导致应用程序死锁。
  • CreateHTMLBody internaly 使用 WinINET http 堆栈来发出请求。此堆栈旨在用于客户端交互场景。在服务器场景中,它不是线程安全的。
  • 您丢失了所有会话上下文,因此它可以(正如您所发现的那样)使某些事情变得更困难或更不安全。此外,它还会产生大量不需要的会话。

虽然它真正的CreateHTMLBody 可以非常方便,但它也可以创建臃肿的电子邮件。在服务器情况下,您确实需要使用代码编写电子邮件,而不是使用这种诱人的方法。

编辑

Jimbo 的想法似乎比 CreateHTMLBody 更通用。一般情况是在 ASP 页面(我们将其指定为“客户端页面”)中使用了一个组件(消费者无法控制该组件),并且它向另一个 ASP 页面(我们将其指定为“服务页面”)。假设“客户端页面”唯一可以控制组件使用的就是提供给它的 URL。

这里有一些方法可以避免或减轻上述问题。

处理锁定问题: 将“客户端页面”和“服务页面”放在不同的 ASP 应用程序中可以避免锁定问题。我的建议是将“客户端页面”放置在与应用程序的其余部分不同的应用程序中,并且这个新应用程序将位于主应用程序的子文件夹中。

处理 WinINET 问题: 将新应用程序放在它自己的应用程序池中。如果以不安全的方式使用 WinINET 确实会导致问题,它不会影响主应用程序进程。事实上,将其置于自己的进程中可能有助于避免此类问题。 (这里不能保证,但它是完全避免 WinINET 问题的最佳方法)。

控制安全性:将“服务页面”配置为仅接受来自“客户端页面”的请求。可能有很多方法可以做到这一点,但最简单的是启用基于 IP 的安全性,对“服务页面”的请求只能来自特定 IP 或至少一组有限的 IP 地址。

处理身份验证: 在主应用程序登录期间,创建一个包含一些唯一值的易失性 cookie。由于“客户端页面”被浏览器视为主应用程序的子文件夹,因此它将接收此 cookie。 “客户端页面”可以使用此cookie来确认请求的真实性和/或在使用组件时将其传递到URL中。

抑制多产会话创建:在“服务页面”完成操作之前调用Session.Abandon

【讨论】:

  • Woo...我不知道 CreateHTMLBody 使用了 WinINET 堆栈。出于同样的原因,我通常会要求客户不要使用 XMLHTTP,而是使用 ServerXMLHTTP。 +1
  • 感谢您的回复。可悲的是,这种类型的应用程序有很多实例,例如使用 PDF 创建控件,该控件也使用类似的 GetContentFromURL - 诸如此类的实例没有替代方案。
猜你喜欢
  • 2017-02-09
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 2010-12-08
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多