我有一个用传统 ASP 编写的 Web 服务。在此 Web 服务中,它尝试通过 DCOM 在另一台服务器上创建 VirtualServer.Application 对象。此操作失败,并显示权限被拒绝。但是,我在同一个远程服务器上的同一个 Web 服务中实例化了另一个组件,该组件创建没有问题。此组件是自定义内部组件。
Web 服务由通过 WinHTTP 调用它的独立 EXE 程序调用。已验证 WinHTTP 已成功使用 Kerberos 向 Web 服务进行身份验证。向 Web 服务进行身份验证的用户是管理员用户。EXE 到 Web 服务的身份验证步骤成功,并使用了 Kerberos。
我已经使用 DCOMCNFG 验证了远程计算机上的 DCOM 权限。默认限制允许管理员进行本地和远程激活、本地和远程访问以及本地和远程启动。默认组件权限也允许这样做。这已经得到验证。工作组件的单个组件权限设置为默认值。VirtualServer.Application 组件的单个组件权限也设置为默认值。基于这些设置,Web 服务应该能够实例化并访问远程计算机上的组件。
在运行两个测试(一个使用工作组件,另一个使用 VirtualServer.Application 组件)时设置 Wireshark 跟踪,会发现一个有趣的行为。当 Web 服务实例化工作自定义组件时,我可以看到连接到 RPCSS 端点映射器的请求首先执行 TCP 连接序列。然后我看到它使用适当的安全包(在本例中为 kerberos)执行绑定请求。在获得工作 DCOM 组件的端点后,它会通过 Kerberos 再次连接到 DCOM 端点进行身份验证,并且它能够成功实例化和通信。
在失败的 VirtualServer.Application 组件上,我再次看到使用 kerberos 的绑定请求成功到达 RPCC 端点映射器。但是,当它随后尝试连接到虚拟服务器进程中的端点时,它无法连接,因为它仅尝试使用 NTLM 进行身份验证,最终失败,因为 Web 服务无权访问执行 NTLM 哈希的凭据。
为什么尝试通过 NTLM 进行身份验证?
附加信息:
- 两个组件通过 DCOM 在同一台服务器上运行
- 两个组件都在服务器上以本地系统身份运行
- 这两个组件都是 Win32 服务组件
- 两个组件具有完全相同的启动/访问/激活 DCOM 权限
- 两个 Win32 服务都设置为作为本地系统运行
- 据我所知,权限被拒绝不是权限问题,而是身份验证问题。权限被拒绝是因为 NTLM 身份验证使用的是 NULL 用户名,而不是 Kerberos 委派
- 在托管 Web 服务的服务器上设置了约束委派。
- 托管 web 服务的服务器被允许委托给 rpcss/dcom-server-name
- 托管 web 服务的服务器被允许委托给 vssvc/dcom-server-name
- 允许 dcom 服务器委托给 rpcss/webservice-server
- 在 dcom 服务器上注册的 SPN 包括 rpcss/dcom-server-name 和 vssvc/dcom-server-name 以及 HOST/dcom-server-name 相关的 SPN
- 在 webservice-server 上注册的 SPN 包括 rpcss/webservice-server 和 HOST/webservice-server 相关的 SPN
有人知道为什么尝试在远程服务器上创建 VirtualServer.Application 对象会回退到 NTLM 身份验证,从而导致其失败并被拒绝权限吗?
附加信息:当以下代码在 webservice 上下文中运行时,直接通过仅测试的、刚开发的 COM 组件运行,它会在指定行上失败并出现访问被拒绝的情况。
COSERVERINFO csi;
csi.dwReserved1=0;
csi.pwszName=L"terahnee.rivin.net";
csi.pAuthInfo=NULL;
csi.dwReserved2=NULL;
hr=CoGetClassObject(CLSID_VirtualServer, CLSCTX_ALL, &csi, IID_IClassFactory, (void **) &pClsFact);
if(FAILED( hr )) goto error1;
// Fails here with HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)
hr=pClsFact->CreateInstance(NULL, IID_IUnknown, (void **) &pUnk);
if(FAILED( hr )) goto error2;
我还注意到,在 Wireshark Traces 中,我看到了尝试连接到服务进程组件仅限请求NTLMSSP 身份验证,它甚至没有尝试使用 kerberos。这表明由于某种原因,Web 服务认为它不能使用 kerberos...
答案1
NTLM 身份验证回退是一种症状。真正的问题是 Kerberos 为何失败。
这听起来像是获得的模拟级别不足以执行请求的活动的典型案例。使用 Kerberos 委派时,如果模拟的机器或进程没有“模拟”令牌,而是具有较低的令牌(例如“身份”),则请求 Kerberos 身份验证以使用其他身份访问资源将失败。
模拟令牌有四种类型:
匿名
身份
模拟
委托
“模拟”允许模拟访问执行模拟的进程所在的同一台计算机上的资源。如果执行模拟的进程正在访问与执行模拟的计算机不同的计算机上的资源,则需要“委托”令牌。这通常需要 TCB 特权(作为操作系统的一部分)。
TokenImpersonationLevel 枚举
http://msdn.microsoft.com/en-us/library/system.security.principal.tokenimpersonationlevel%28v=vs.80%29.aspx
请注意,Windows XP/Server 2003 中的 DCOM 默认模拟级别为“身份”。这意味着进程在模拟其他身份时可能无法访问资源。您可能希望尝试机器范围或进程级别的安全配置,以找到有效的方法。您可能会发现需要启用加密才能连接到某些资源。将一项服务配置为与另一项服务相同可能不是一回事。
不同操作系统之间的连接
http://msdn.microsoft.com/en-us/library/aa389284%28v=vs.85%29.aspx
使用 DCOMCNFG 设置系统范围的安全性
http://msdn.microsoft.com/en-us/library/ms680051%28v=vs.85%29.aspx
使用 C++ 设置默认进程安全级别
http://msdn.microsoft.com/en-us/library/aa393617%28v=vs.85%29.aspx