16.2 用户账户模拟
知识点讲解:光盘:视频\PPT讲解(知识点)\第16章\用户账户模拟.mp4
在ASP.NET系统中,是默认低级别账户权限的。ASP.NET默认不模拟发出请求的用户,这样可能发生以下情况:
- 由于ASP.NET系统账户默认权限不够高,不能执行一些对权限要求比较高的操作(如磁盘访问、活动目录操作等)。
- ASP.NET系统账户权限设置得过高,匿名用户都能执行“危险”操作。
实例076 获取指定文件的列表信息
源码路径 光盘\daima\16\Web 视频路径 光盘\视频\实例\第16章\076
本实例的实现文件是zhanghu.aspx和zhanghu.aspx.cs,具体实现过程如下。
(1)文件zhanghu.aspx是显示页面,分别显示按钮控件和一个GridView控件,主要实现代码如下。
<asp:Button ID="btn_GetFileList" runat="server" OnClick="btn_GetFileList_Click"
Text="获取文件列表" />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
(2)文件zhanghu.aspx.cs是后台处理页面,其中在Page_Load中设置输出请求标识和身份验证类型。其主要实现代码如下。
protected void Page_Load(object sender, EventArgs e)
{
WindowsIdentity userIdentity = WindowsIdentity.GetCurrent();
WindowsPrincipal userPrincipal = new WindowsPrincipal(userIdentity);
Response.Write(string.Format("当前用户标识:{0}<br/>" , userPrincipal.
Identity.Name));
Response.Write(string.Format("身份验证类型:{0}<br/>" , userPrincipal.
Identity.AuthenticationType));
}
范例151:查询指定列数据
源码路径:光盘\演练范例\151
视频路径:光盘\演练范例\151
范例152:列别名和表别名
源码路径:光盘\演练范例\152
视频路径:光盘\演练范例\152
设置按钮控件的单击事件处理方法,具体实现代码如下。
protected void btn_GetFileList_Click(object sender, EventArgs e)
{
DirectoryInfo di = new DirectoryInfo(@"d:\text");
GridView1.DataSource = di.GetFiles();
GridView1.DataBind();
}
(3)最后,新建一个Web.config文件,设置开启模拟,主要实现代码如下。
<?xml version="1.0"?>
<configuration>
<system.web>
<identity impersonate="true"/> <!--开启模拟-->
</system.web>
</configuration>
(4)配置IIS,把程序所在的目录配置成一个虚拟目录,并且设置这个虚拟目录为关闭匿名访问,开启Windows集成验证,如图16-2所示。
图16-2 关闭此虚拟目录的匿名访问
(5)运行实例程序,单击【获取文件列表】按钮,如图16-3所示。
图16-3 获取文件列表信息
可以看到,当前模拟的用户为请求的用户(按【Ctrl+Alt+Del】组合键也可以看到当前登录的用户信息),由于当前请求的用户为本地的管理员(拥有操作本机d:\Text的权限),GridView显示了目录下的所有文件信息。
在上述实例中,实现了一个简单的模拟请求用户效果。读者如果右键依次单击【我的电脑】︱【管理】命令,在“本地用户和组”下的“用户”文件夹中找到ASPNET用户,右键单击并选择【属性】命令,打开【ASP.NET属性】对话框,如图16-4所示,在其中可以看到ASPNET账户隶属于Users这个用户组。
图16-4 ASPNET账户隶属于Users用户组
笔者的运行系统是Windows XP操作系统(IIS 5.1),对于IIS 6.0而言,ASP.NET默认运行于NetworkService系统账户。如果此时查看目标文件“d:\Text”文件夹的权限,如图16-5所示。
图16-5 “Test”文件夹的权限
可以看到,Users用户组不具有对这个文件夹的任何权限。那么,如果关闭模拟,ASP.NET页面以ASPNET系统账户来执行的话,应该就没有权限访问“Test”文件夹了。设置<identity impersonate="false"/>,然后重新运行页面。单击【获取文件列表】按钮,出现“访问拒绝”的异常,如图16-6所示。
图16-6 ASPNET账户对文件夹的访问被拒绝
给“Test”文件夹添加ASPNET系统账户并赋予读取和运行权限,如图16-7所示。
图16-7 赋予ASPNET系统账户对文件夹的操作权限
重新运行页面后能正常获取文件列表,如图16-8所示。
图16-8 模拟请求用户
16.2.1 模拟某一个用户
如果Web服务器上有多个ASP.NET应用程序,或者ASP.NET应用程序需要更高的权限,以执行特殊的操作,则可以为程序设置一个单独的账户。此时需要在配置文件web.config中编写如下代码。
<?xml version="1.0"?>
<configuration>
<system.web>
<identity impersonate="true"
userName="域\机器名"
password="密码"
/>
</system.web>
</configuration>
在上述配置代码中,可以设置登录需要的用户名和密码,此处设置的登录账户需要对以下目录拥有操作权限。
- ASP.NET临时文件夹。这是ASP.NET动态编译的位置,需要有读写权限。
- 全局程序集缓存(%Windir%\assembly)。这是全局程序集缓存,需要有读取权限。
如果正在运行Windows Server 2003,其中的IIS 6.0配置为运行在辅助进程隔离模式下(默认情况),则可通过将ASP.NET应用程序配置为在自定义应用程序池(在特定的域标识下运行)中运行,然后使用指定的域标识访问资源而无需使用模拟。
16.2.2 实现临时模拟
有时候用户可能需要暂时模拟经过身份验证的调用方,此时需要编写代码来实现这个临时模拟。具体实现过程如下。
(1)把实例076中的Page_Load中的代码封装成一个私有方法并删除Page_Load中的代码。
private void GetIdentityInfo()
{
WindowsIdentity userIdentity = WindowsIdentity.GetCurrent();
WindowsPrincipal userPrincipal = new WindowsPrincipal(userIdentity);
Response.Write(string.Format("系统用户标识:{0}<br/>", userPrincipal.
Identity.Name));
Response.Write(string.Format("身份验证类型:{0}<br/>", userPrincipal.
Identity.AuthenticationType));
}
(2)修改【获取文件列表】按钮的单击事件处理方法。
protected void btn_GetFileList_Click(object sender, EventArgs e)
{
GetIdentityInfo();
WindowsIdentity userIdentity = (WindowsIdentity)User.Identity;
WindowsPrincipal userPrincipal = new WindowsPrincipal(userIdentity);
WindowsImpersonationContext ctx = null;
try
{
Response.Write("模拟开始<br/>");
ctx = userIdentity.Impersonate();
GetIdentityInfo();
DirectoryInfo di = new DirectoryInfo(@"d:\test");
GridView1.DataSource = di.GetFiles();
GridView1.DataBind();
}
catch
{
}
finally
{
Response.Write("模拟结束<br/>");
if (ctx != null)
ctx.Undo();
GetIdentityInfo();
}
}
可以看到,输出了3次当前用户标识,分别是开始模拟以前、模拟以后和恢复不模拟以后。
(3)修改Web.config文件,以禁止模拟,然后禁止ASPNET账户对d:\Test文件夹的读取权限。运行效果如图16-9所示。
图16-9 临时模拟运行效果