2

在 Cassini-dev 的 NTLM 身份验证类中的这段代码中,对 SECUR32.DLL(通过Interop)进行的调用是为了对 HTTP 请求Authorization标头中的 base64 编码数据进行身份验证。这是有道理的,当AcceptSecurityContext()QuerySecurityContextToken()都返回0时,客户端已被授权。最后,安全上下文令牌SecurityIdentifier从中提取了一个(_sid变量)。(关于常见安全 ID的一些信息)

这是NtlmAuth 类的相关部分

int num = Interop.AcceptSecurityContext(ref _credentialsHandle, zero,
                     ref _inputBufferDesc, 20,
                     0, ref _securityContext, ref _outputBufferDesc,
                     ref _securityContextAttributes, ref _timestamp);
if (num == 0x90312)
{
    securityContextAcquired = true;
    _blob = Convert.ToBase64String(inArray, 0, (int) _outputBuffer.cbBuffer);
}
else
{
    if (num != 0)
    {
        return false;
    }
    IntPtr phToken = IntPtr.Zero;
    if (Interop.QuerySecurityContextToken(ref _securityContext, ref phToken) != 0)
    {
         return false;
    }
    try
    {
         using (WindowsIdentity identity = new WindowsIdentity(phToken))
    {
         _sid = identity.User;
    }
}
finally
{
    Interop.CloseHandle(phToken);
}
_completed = true;

Request Class中,在TryNtlmAuthenticate()使用 NtlmAuth 的方法中,在成功完成 NTLM 身份验证的 3 个步骤后,在返回最终403或完成请求之前,将进行最后一次检查:

if (_host.GetProcessSid() != auth.SID)
{
    _connection.WriteErrorAndClose(0x193);
    return false;
}

在这里,_host.GetProcessSid()SecurityIndentifierCassini 进程(我)的所有者,而auth.SIDSecurityIdentifier经过身份验证的用户(上面NtlmAuth类中的 _sid)。如果这 2 个 SID 不同,则返回 403 并停止身份验证,否则将请求提供给浏览器。


我的问题是:

  1. 为什么需要比较 2 个不同用户的 SecurityIndentifiers?当我尝试使用不是拥有 Cassini 进程的用户的用户/密码进行 NTLM 身份验证时,这将失败(返回 403)。
  2. 如果这确实是预期的行为,如果 Cassini 将作为 Windows 服务运行,则没有人能够登录,因为主机 SID 将是S-1-5-18(或者可能类似的东西,取决于操作系统版本)和没有人可以作为操作系统登录。这只是 Cassini 的 NTLM 身份验证实现的一部分,我没有正确使用 Cassini 吗?
  3. 如果这显然不是预期的行为,那么 SecurityIndentifiers 在这种情况下扮演什么角色?是否需要进行额外检查以确保主机 SID 需要属于某个类或组才能接受某个类/组的客户端 SID?处理主机/客户端 SID 时是否存在操作系统版本 (XP/Vista/7) 影响?
  4. 或者这里没有安全标识符的适用用途,因为它们没有被存储或传递,也没有被用来进一步识别用户/客户端?

更新:似乎有人在 cassinidev 论坛上提出了一个补丁,该补丁早在 2010 年就删除了此 SID 检查(补丁 #6604),但仍在评估中。

4

1 回答 1

1

不是答案,但我只是注意到一个类似的问题,但表现形式略有不同:当托管在 Windows 服务中并且 Cassini-dev 配置为使用 Windows 身份验证时,HttpContext.Current.User 是服务正在运行的帐户下,而不是提出请求的用户。

对我来说,这似乎是 cassini-dev 中的一个错误。

于 2011-12-01T18:40:48.347 回答