本教程阐释在 ASPNET 版中IIS 集成 Windows 身份验证以及 ASPNET 的Windows 身份验证的工作机制同时阐释 NTLM 和 Kerberos 身份验证的工作机制此外本教程还阐释 WindowsAuthenticationModule 类如何构造 WindowsPrincipal 和 WindowsIdentity 对象然后将这些对象附加到当前的 ASPNET Web 请求以表示经过身份验证的用户
概述
身份验证是一个验证客户端身份的过程通常采用指定的第三方授权方式客户端可能是最终用户计算机应用程序或服务客户端的标识称为安全原则为了使用服务器应用程序进行验证客户端提供某种形式的凭据来允许服务器验证客户端的标识确认了客户端的标识后应用程序可以授予执行操作和访问资源的原则
如果应用程序使用 Active Directory 用户存储则应该使用集成 Windows 身份验证对 ASPNET 应用程序使用集成 Windows 身份验证时最好的方法是使用 ASPNET 的 Windows 身份验证提供程序附带的 Internet 信息服务 (IIS) 身份验证方法使用该方法将自动创建一个 WindowsPrincipal 对象(封装一个 WindowsIdentity 对象)来表示经过身份验证的用户您无需编写任何身份验证特定的代码
ASPNET 还支持使用 Windows 身份验证的自定义解决方案(避开了 IIS 身份验证)例如可以编写一个根据 Active Directory 检查用户凭据的自定义 ISAPI 筛选器使用该方法必须手动创建一个 WindowsPrincipal 对象
ASPNET 身份验证
IIS 向 ASPNET 传递代表经过身份验证的用户或匿名用户帐户的令牌该令牌在一个包含在 IPrincipal 对象中的 IIdentity 对象中维护IPrincipal 对象进而附加到当前 Web 请求线程可以通过 HttpContextUser 属性访问 IPrincipal 和 IIdentity 对象这些对象和该属性由身份验证模块设置这些模块作为 HTTP 模块实现并作为 ASPNET 管道的一个标准部分进行调用如图 所示
图 ASPNET 管道
ASPNET 管道模型包含一个 HttpApplication 对象多个 HTTP 模块对象以及一个 HTTP 处理程序对象及其相关的工厂对象HttpRuntime 对象用于处理序列的开头在整个请求生命周期中HttpContext 对象用于传递有关请求和响应的详细信息
有关 ASPNET 请求生命周期的详细信息请参阅ASPNET Life Cycle网址是 (enUSVS)aspx
身份验证模块
ASPNET 在计算机级别的 nfig 文件中定义一组 HTTP 模块其中包括大量身份验证模块如下所示
<httpModules> <add name=WindowsAuthentication
type=SystemWebSecurityWindowsAuthenticationModule />
<add name=FormsAuthentication
type=SystemWebSecurityFormsAuthenticationModule />
<add name=PassportAuthentication
type=SystemWebSecurityPassportAuthenticationModule />
</httpModules>
只加载一个身份验证模块这取决于该配置文件的 authentication 元素中指定了哪种身份验证模式该身份验证模块创建一个 IPrincipal 对象并将它存储在 HttpContextUser 属性中这是很关键的因为其他授权模块使用该 IPrincipal 对象作出授权决定
当 IIS 中启用匿名访问且 authentication 元素的 mode 属性设置为 none 时有一个特殊模块将默认的匿名原则添加到 HttpContextUser 属性中因此在进行身份验证之后HttpContextUser 绝不是一个空引用(在 Visual Basic 中为 Nothing)
WindowsAuthenticationModule
如果 nfig 文件包含以下元素则激活 WindowsAuthenticationModule 类
<authentication mode=Windows />
WindowsAuthenticationModule 类负责创建 WindowsPrincipal 和 WindowsIdentity 对象来表示经过身份验证的用户并且负责将这些对象附加到当前 Web 请求
对于 Windows 身份验证遵循以下步骤
WindowsAuthenticationModule 使用从 IIS 传递到 ASPNET 的 Windows 访问令牌创建一个 WindowsPrincipal 对象该令牌包装在 HttpContext 类的 WorkerRequest 属性中引发 AuthenticateRequest 事件时WindowsAuthenticationModule 从 HttpContext 类检索该令牌并创建 WindowsPrincipal 对象HttpContextUser 用该 WindowsPrincipal 对象进行设置它表示所有经过身份验证的模块和 ASPNET 页的经过身份验证的用户的安全上下文
WindowsAuthenticationModule 类使用 P/Invoke 调用 Win 函数并获得该用户所属的 Windows 组的列表这些组用于填充 WindowsPrincipal 角色列表
WindowsAuthenticationModule 类将 WindowsPrincipal 对象存储在 HttpContextUser 属性中随后授权模块用它对经过身份验证的用户授权
注DefaultAuthenticationModule 类(也是 ASPNET 管道的一部分)将 ThreadCurrentPrincipal 属性设置为与 HttpContextUser 属性相同的值它在处理 AuthenticateRequest 事件之后进行此操作