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

例如:

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 对象,从而不需要身份验证?

有帮助吗?

解决方案

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

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

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

编辑

Jimbo 似乎不仅仅考虑了 CreateHTMLBody,还考虑了更通用的场景。一般情况是,在 ASP 页面(我们将其指定为“客户端页面”)中使用组件(使用者无法控制该组件),并且它向另一个 ASP 页面(我们将其指定为“客户端页面”)发出后续请求(可能通过 WinINET)。将指定其为“服务页面”)。假设“客户端页面”唯一可以控制组件使用的是提供给它的 URL。

以下是一些避免或减轻上述问题的方法。

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

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

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

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

抑制大量会话创建: 拨打“服务页面” Session.Abandon 在其完成其操作之前。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top