📄 。net安全性.txt
字号:
txtUserName.Text,
false ));
}
}
创建一个 IPrincipal 对象
在 Global.asax 内的 Application_AuthenticationRequest 事件处理程序中创建 IPrincipal 对象。除非您需要基于角色的扩展功能,否则,请使用 GenericPrincipal 类。在这种情况下,创建一个实现 IPrincipal 的自定义类。
将 IPrincipal 对象放到当前的 HTTP 上下文中
下面显示了 GenericPrincipal 对象的创建过程。
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
// 提取窗体身份验证 cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if(null == authCookie)
{
// 没有身份验证 cookie。
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch(Exception ex)
{
// 记录异常情况详细信息(为简便起见,已省略)
return;
}
if (null == authTicket)
{
// 无法解密 Cookie。
return;
}
// 创建票证后,为 UserData 属性指定一个
// 角色名的以管道符分隔的字符串。
string[] roles = authTicket.UserData.Split(new char[]{'|'});
// 创建一个标识对象
FormsIdentity id = new FormsIdentity( authTicket );
// 该主体将通过整个请求。
GenericPrincipal principal = new GenericPrincipal(id, roles);
// 将新的主体对象附加到当前的 HttpContext 对象
Context.User = principal;
}
基于用户名或角色成员身份对用户进行授权
使用声明方式的主体权限要求来限制对方法的访问。使用强制方式的主体权限要求和/或明确角色检查 (IPrincipal.IsInRole) 在方法中执行细分的授权。
窗体实现原则
? 当使用 HTML 窗体捕获凭据时,请使用 SSL。
无论何时通过网络发送凭据或身份验证 Cookie,除了对登录页使用 SSL 外,还应该对其他页使用 SSL。这样,可以减轻与 Cookie 重播攻击相关的威胁。
? 根据自定义数据存储验证用户的身份。请使用 SQL Server 或 Active Directory。
? 从自定义数据存储中检索角色列表,并在 FormsAuthenticationTicket 类的 UserData 属性中存储分隔的角色列表。这样,不必为每个 Web 请求重复访问数据存储,从而提高了性能;而且还免去了在身份验证 Cookie 中存储用户凭据的麻烦。
? 如果角色列表很大并且有超过 Cookie 大小限制的危险,请在 ASP.NET 缓存对象或数据库中存储角色的详细信息,并在每个后续请求中检索这些信息。
? 对于初始身份验证后的每个请求:
? 在 Application_AuthenticateRequest 事件处理程序中,从票证中检索角色。
? 创建一个 IPrincipal 对象并将其存储在 HTTP 上下文 (HttpContext.User) 中。.NET Framework 还将其与当前 .NET 线程 (Thread.CurrentPrincipal) 关联起来。
? 除非您有特殊的原因需要创建自定义的 GenericPrincipal 实现(例如,支持基于角色的增强操作),否则请使用 IPrincipal 类。
? 使用两种 Cookie:一种用于个性化,另一种用于安全的身份验证和授权。将个性化 Cookie 作为永久性的 Cookie(确保它不包含允许请求执行受限操作的信息;例如在站点中的安全部分下订单)。
? 对于每个 Web 应用程序,请使用单独的 Cookie 名称(使用 Forms 元素的 Forms 属性)和路径。如果针对某个应用程序验证了用户的身份,这可确保在使用同一 Web 服务器承载的第二个应用程序时,不会将这些用户作为已验证身份的用户处理。
? 确保在客户端浏览器中启用 Cookie。对于不需要 Cookie 的窗体身份验证方法,请参见本章后面的“无 Cookie 窗体身份验证”。
更多信息
? 请参见本指南中的如何将窗体身份验证用于 SQL Server 2000。
? 请参见本指南中的如何将窗体身份验证用于 Active Directory。
? 请参见本指南中的如何利用窗体身份验证创建 GenericPrincipal 对象。
承载多个使用窗体身份验证的应用程序
如果在同一 Web 服务器上承载多个使用窗体身份验证的 Web 应用程序,在某一应用程序中已验证身份的用户可以请求另一个应用程序,而无需重定向到该应用程序的登录页。第二个应用程序中的 URL 授权规则可能会拒绝该用户的访问,而不会提供使用登录窗体提供登录凭据的机会。
仅在以下情况下发生这种情况:多个应用程序的 <forms> 元素的名称和路径属性是相同的,而且每个应用程序在 Web.config 中使用相同的 <machineKey> 元素。
更多信息
有关此问题的详细信息以及解决方法,请参见以下知识库文章:
? Q313116:PRB: Forms Authentication Requests Are Not Directed to loginUrl Page(PRB:没有将窗体身份验证请求定向到 loginUrl 页)
? Q310415:PRB: Mobile Forms Authentication and Different Web Applications(PRB:移动窗体身份验证和各种 Web 应用程序)
无 Cookie 窗体身份验证
如果您需要无 Cookie 窗体身份验证解决方案,请考虑使用 Microsoft Mobile Internet Toolkit 所使用的方法。移动窗体身份验证建立在窗体身份验证的基础之上,但使用查询字符串来传递身份验证票证而不是使用 Cookie。
更多信息
有关移动窗体身份验证的详细信息,请参见 Microsoft 知识库文章 Q311568 INFO: How To Use Mobile Forms Authentication with Microsoft Mobile Internet Toolkit(INFO:如何将移动窗体身份验证用于 Microsoft Mobile Internet Toolkit)。
返回页首
Passport 身份验证
如果应用程序用户使用 Passport 帐户,而且您要在其他支持 Passport 的站点上实现单次登录解决方案,则应使用 Passport 身份验证。
当将 ASP.NET 配置为使用 Passport 身份验证时,就会提示用户登录并将该用户重定向到 Passport 站点。在成功验证了凭据后,就会将用户重定向回您的站点。
将 ASP.NET 配置为使用 Passport 身份验证。
若要将 ASP.NET 配置为使用 Passport 身份验证,请使用以下 Web.config 设置。
<authentication mode="Passport">
<passport redirectUrl="internal" />
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
将 Passport 标识映射为 Global.asax 中的角色
若要将 Passport 标识映射为角色,请按如下所示在 Global.asax 中实现 PassportAuthentication_OnAuthentication 事件处理程序。
void PassportAuthentication_OnAuthenticate(Object sender,
PassportAuthenticationEventArgs e)
{
if(e.Identity.Name == "0000000000000001")
{
string[] roles = new String[]{"Developer", "Admin", "Tester"};
Context.User = new GenericPrincipal(e.Identity, roles);
}
}
测试角色成员身份
以下代码片段显示了如何在 aspx 页中检索已验证身份的 Passport 标识和检查角色成员身份。
PassportIdentity passportId = Context.User.Identity as PassportIdentity;
if (null == passportId)
{
Response.Write("Not a PassportIdentity<br>");
return;
}
Response.Write("IsInRole:Develeoper? " + Context.User.IsInRole("Developer"));
返回页首
自定义身份验证
如果 .NET Framework 提供的身份验证模块均不能满足您的确切身份验证需要,则可以使用自定义身份验证并实现您自己的身份验证机制。例如,您的公司可能已经制订了一个可由其他应用程序广泛使用的自定义身份验证策略。
若要在 ASP.NET 中实现自定义身份验证,请执行下列操作:
? 按如下所示在 Web.config 中配置身份验证模式。这将通知 ASP.NET 不要调用它的任何内置身份验证模块。
<authentication mode="None" />
? 创建实现 System.Web.IHttpModule 接口的类以创建自定义的 HTTP 模块。此模块应该挂钩到 HttpApplication.AuthenticateRequest 事件中,并在要求身份验证时对每个应用程序请求提供要调用的委派。
身份验证模块必须:
? 从调用方获取凭据。
? 根据存储验证凭据。
? 创建一个 IPrincipal 对象并将其存储在 HttpContext.User 中。
? 创建并保护验证身份令牌,并将其发回到用户(通常在查询字符串、Cookie 或隐藏的窗体字段中)。
? 在后续请求中获取身份验证令牌,对它进行验证,然后重新发出。
更多信息
有关如何实现自定义 HTTP 模块的详细信息,请参见 Microsoft 知识库文章 Q307996 HOW TO: Create an ASP.NET HTTP Module Using Visual C# .NET(如何使用 Visual C# .NET 创建 ASP.NET HTTP 模块)。
返回页首
ASP.NET 的进程标识
使用权限最少的帐户运行 ASP.NET(具体来说就是 Aspnet_wp.exe 辅助进程)。
使用权限最少的帐户
使用权限最少的帐户可以减少与进程攻击相关的威胁。如果某个顽固的攻击者设法破坏了运行 Web 应用程序的 ASP.NET 进程,则这些应用程序可以轻易地继承和使用给该进程帐户授予的特权和访问权限。配置为权限最少的帐户可以限制可能的潜在危害。
避免作为 SYSTEM 运行
不要使用高权限的 SYSTEM 帐户来运行 ASP.NET,也不要给 ASP.NET 进程帐户授予“作为操作系统的一部分”权限。您可能很想使用其中的一种方法,通过代码调用 LogonUser API 以获取固定的标识(通常用于网络资源访问)。有关替代方法,请参见本章后面的“访问网络资源”。
不要以 SYSTEM 的身份运行或不授予“作为操作系统的一部分”权限的原因包括:
? 当系统遭到攻击时,它会大大增加攻击者所造成的危害,但不能增加防范攻击的能力。
? 它破坏了最少权限原则。已将 ASPNET 帐户明确配置为运行 ASP.NET Web 应用程序使用的权限最少的帐户。
更多信息
有关“作为操作系统的一部分”权限的详细信息,请参见 1999 年 8 月的 Microsoft Systems Journal 专栏文章 Security Briefs(安全性简介)。
域控制器和 ASP.NET 进程帐户
一般情况下,不建议在域控制器上运行 Web 服务器,因为对该服务器的攻击就是对域的攻击。正如 Microsoft 知识库文章 Q315158:BUG: ASP.NET Does Not Work with the Default ASPNET Account on a Domain Controller(BUG:在域控制器上 ASP.NET 不能使用默认 ASPNET 帐户)”中所述,如果需要在域控制器上运行 ASP.NET,则需要给 ASP.NET 进程帐户授予相应的权限。
使用默认 ASPNET 帐户
已将本地 ASPNET 帐户明确配置为使用尽可能最少的权限集运行 ASP.NET Web 应用程序。如果可能,尽量使用 ASPNET。
正如 Machine.config 中的 <processModel> 元素所配置的一样,默认情况下,ASP.NET Web 应用程序使用此帐户运行。
<processModel userName="machine" password="AutoGenerate" />
注意:machine 用户名表示 ASPNET 帐户。当安装 .NET Framework 时,使用加密型强密码创建该帐户。除了在安全帐户管理器 (SAM) 数据库中进行配置外,还将密码存储在本地计算机上的本地系统授权 (LSA) 中。当系统启动 ASP.NET 辅助进程时,系统就会从 LSA 中检索密码。
如果应用程序访问网络资源,则 ASPNET 帐户必须能够由远程计算机验证身份。您有两种选择:
? 将 ASPNET 帐户的密码重置为某个已知值,然后在远程计算机上创建一个重复帐户(具有相同的名称和密码)。在以下情况下,此方法是唯一的选择:
? Web 服务器和远程计算机位于单独的域中,并且域之间没有信任关系。
? Web 服务器和远程计算机由防火墙隔开,而且您不想打开支持 Windows 身份验证所需的端口。
? 如果您主要关心管理简便性问题,请使用权限最少的域帐户。
若要避免必须手动更新和同步密码,可以使用权限最少的域帐户运行 ASP.NET。一定要完全锁定域帐户以减轻进程攻击的威胁。如果某个攻击者设法攻击了 ASP.NET 辅助进程,则该攻击者将有权访问域资源,除非该帐户已完全锁定。
注意:如果您使用本地帐户而且该帐户已被攻击,则唯一遭受攻击的计算机是您在上面创建重复帐户的计算机。如果您使用域帐户,则该帐户对域中的每台计算机都是可见的。但是,该帐户仍然需要拥有访问这些计算机的权限。
<processModel> 元素
Machine.config 文件中的 <processModel> 元素包含 userName 和 password 属性,这些属性指定应该使用哪个帐户来运行 ASP.NET 辅助进程 (Aspnet_wp.exe)。
注意:与传统 ASP 应用程序的运行方式相比,ASP.NET 代码从不在 dllhost.exe 进程中运行或作为 IWAM_MACHINENAME 帐户运行,即使在 IIS 中将应用程序保护级别设置为“高”(“独立”)。
发送到 IIS 的 ASP.NET 请求被直接路由到 ASP.NET 辅助进程 (Aspnet_wp.exe)。ASP.NET ISAPI 扩展 Aspnet_isapi.dll 在 IIS (Inetinfo.exe) 进程地址空间中运行。(这是由 InProcessIsapiApps 元数据库项控制的;不要修改该元数据库项)。ISAPI 扩展负责将请求路由到 ASP.NET 辅助进程。然后,ASP.NET 应用程序在 ASP.NET 辅助进程中运行,其中应用程序域提供隔离边界。
在 IIS 6 中,您可以通过配置应用程序池来隔离 ASP.NET 应用程序,其中每个池都有自己的应用程序实例。
您可以使用多种选项来配置 <processModel> userName 属性。例如:
? machine。辅助进程作为最少权限的默认 ASPNET 帐户运行。此帐户拥有网络访问权限,但不能在网络上的任何其他计算机上验证该帐户的身份,因为此帐户是计算机的本地帐户,并且没有颁发机构担保此帐户。在网络上,此帐户表示为“MachineName\ASPNET”。
? system。辅助进程作为本地 SYSTEM 帐户运行。此帐户在本地计算机上具有广泛的权限,而且还能够使用计算机的凭据访问网络。在网络上,此帐户表示为“DomainName\MachineName$”。
? 特定凭据。当您为 userName 和 password 提供凭据时,请记住最少权限原则。如果您指定本地帐户,则在网络上不能对 Web 应用程序进行身份验证,除非您在远程计算机上创建重复帐户。如果您选择使用权限最少的域帐户,请确保它仅有权访问网络上所需的计算机。
存储加密的 <processModel> 凭据
如果您使用自定义凭据,请使用 aspnet_setreg.exe 实用程序将加密凭据存储在注册表中。不要将纯文本形式的凭据存储在 machine.config 中。
有关此实用程序和下载它的详细信息,请参见 Microsoft 知识库文章 Q329290 HOWTO: Use the ASP.NET Utility to Encrypt Credentials and Session State Connection Strings(HOW TO:使用 ASP.NET 工具加密凭据和会话状态连接字符串)。
下面的示例显示了使用该实用程序之前和之后的 userName 和 password 属性的格式。请注意属性值是如何指向包含加密凭据的安全注册表项和指定值的。
<!-- 之前 -->
<processModel userName="SomeCustomAccount"
password="ClearTextPassword" . . ./>
<!-- 之后 -->
<processModel
userName="registry:HKLM\SOFTWARE\YourSecureApp\processModel\
ASPNET_SETREG,userName"
password="registry:HKLM\SOFTWARE\YourSecureApp\processModel\
ASPNET_SETREG,password" . . ./>
更多信息
? 有关从 ASP.NET Web 应用程序访问网络资源的详细信息,请参见本章后面的访问网络资源。
? 有关如何创建用于运行 ASP.NET 的自定义帐户的详细信息,请参见本指南中的如何创建自定义帐户来运行 ASP.NET。
返回页首
模拟
随着 FileAuthorizationModule 的引入以及有效地使用网关守卫和信任边界,模拟技术在 ASP.NET 中现在看来是弊大于利。
模拟和本地资源
如果使
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -