我的任务是将旧的 ASP 应用程序从 Windows 2003 服务器 (x86) 移植并移动到运行 IIS 7.5 的 Windows 2008R2 服务器
许多事情需要更改(主要与注册表访问有关),但我偶然发现了一个我无法以令人满意的方式解决的问题。
该应用程序使用外部 COM 对象(进程内 dll)。它将在登录阶段创建该对象的实例并将其存储为会话变量。
这曾经工作得很好并且在我的测试中运行良好但是当我将它部署在第一台生产服务器上时,当用户尝试登录时我开始出现随机的“500”错误。错误真的不一致所以我使用procmon来追查问题的根源,发现:当用户尝试访问该网站时,IIS 工作进程尝试打开托管 COM 对象的 Dll,但因访问被拒绝错误而失败。
现在,我不明白这一点:Web 应用程序使用服务帐户来访问本地资源。该服务帐户对该 COM 库所在的目录具有明确的权限。然而,对该文件的访问仍然被拒绝。
我通过为“每个人”提供对 dll 的显式读取和执行访问权限来“解决”这个问题,它(似乎)已经解决了这个问题。
但我不知道为什么。
最奇怪的是,我使用本地管理员帐户连接到网页一次(而且只有一次),然后只要应用程序没有被回收,问题就得到了解决。
如果有人能阐明这个问题,我将不胜感激。我可以接受修复,但我真的很想了解。
编辑澄清一下:该网站未设置为模拟连接用户。事实上,唯一启用的身份验证方案是“匿名身份验证”。但是,基本设置设置为使用服务帐户。
编辑拒绝访问期间 procmon 报告的身份是“IIS APPPOOL\(application name)”
我想你已经回答了你自己的问题。
您的 Web 应用程序配置为模拟经过身份验证的用户。
当请求被接受时,处理请求的线程将获得经过身份验证的用户的令牌,然后该身份将用于该线程的所有操作,直到请求终止。
COM 对象只需要加载一次,管理员基本上可以读取任何文件,因此作为管理员的第一个请求能够 a) 读取文件和 b) 将其加载到进程地址空间中。这通常不需要重复发生:一旦 DLL 在内存中,它就在那里。
如果普通用户(或匿名用户)进行身份验证并被冒充,他们首先没有权限打开文件,ProcMon 应该向您显示这一点,以及正在使用的身份。(默认情况下:匿名请求的 IUSR)。
您描述的“服务帐户”位听起来像是工作进程身份。它们仅用于启动应用程序池、读取配置,然后用于执行与请求不直接相关的事情*。
* 除非您将 App Pool 帐户用作匿名用户帐户,并且除非模拟用户的线程无法开箱即用(即需要委托),在这种情况下将使用 App Pool 帐户。