一.ASP.NET模拟简介
缺省情况下,ASP.NET应用程序以本机的ASPNET帐号运行(当机器上安装.net framework 后,操作系统会自动生成这个帐号),该帐号属于普通用户组,权限受到一定的限制,以保障ASP.NET应用程序运行的安全.但有时需要某个ASP.NET应用程序或程序中的某段代码执行需要特定权限的操作,比如某个文件的存取,这时就需要给该程序或相应的某段代码赋予某个帐号的权限以执行该操作,这种方法称之为身份模拟(Impersonation).-------摘自MSDN,WebCast,邵志东的讲座ASP.NET的安全性.
二.具体应用.
在ASP.NET应用程序中使用身份模拟一般用于资源访问控制.而最实用的启用模拟的方法是:在代码中模拟IIS认证帐号.因为这种方法比较灵活,可以在指定的代码段中使用身份模拟,在该代码段之外再恢复使用ASPNET本机帐号.
使用该方法的要求:
1.必须使用Windows的认证身份标志.
也即在web.config中有如下配置:
<authentication mode="Windows" />
2.不允许使用匿名访问该页面.
也即在web.config中有如下配置:
<authorization>
<deny users="?"/>
</authorization>
三.代码示例.
using
System.IO;
namespace AspFileOp
... {
/**//// <summary>
/// FileOperate 的摘要说明。
/// </summary>
public class FileOperate : System.Web.UI.Page
...{
protected System.Web.UI.WebControls.TextBox tbContext;
protected System.Web.UI.WebControls.Button btCreate;
protected System.Web.UI.WebControls.Button btWrite;
private void Page_Load(object sender, System.EventArgs e)
...{
if(!this.IsPostBack )
...{
// 在代码中模拟IIS认证帐号
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//在下面的代码段里,代码的具有管理员的权限可以对服务器或本地上已有的文件进行存取,删除等所有权限的操作.
StreamWriter sw = new StreamWriter(Server.MapPath("TestFile.txt"),true);
sw.WriteLine("Liuxibnao");
sw.Close();
File.Delete(Server.MapPath("TestFile.txt"));
//----END
impersonationContext.Undo();
}
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
...{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
...{
this.btWrite.Click += new System.EventHandler(this.btWrite_Click);
this.btCreate.Click += new System.EventHandler(this.btCreate_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void btWrite_Click(object sender, System.EventArgs e)
...{
//此段代码没有模拟ASP.NET,所以他就以本机的ASPNET帐号运行,该帐号属于普通用户组,对文件的权限将受到限制.
//对已有的文件读是正常的.
StreamReader sr = new StreamReader(Server.MapPath("NewCreateText.txt"));
string strLine="";
strLine= sr.ReadToEnd();
sr.Close();
tbContext.Text = strLine;
//但对已有的文件写是会产生异常的.
StreamWriter sw = new StreamWriter(Server.MapPath(""),true);
sw.WriteLine("Hello File System");
sw.Close();
}
private void btCreate_Click(object sender, System.EventArgs e)
...{
//此段代码由于文件是代码自己产生的,所以此段代码拥有对文件的所有操作权限,不需要模拟ASP.NET
FileStream fout = new FileStream(Server.MapPath("Hello.txt"),FileMode.Create,FileAccess.Write);
StreamWriter sw = new StreamWriter(fout);
sw.WriteLine("Hello,world");
sw.Close();
fout.Close();
File.Delete(Server.MapPath("Hello.txt"));
}
}
}
namespace AspFileOp
... {
/**//// <summary>
/// FileOperate 的摘要说明。
/// </summary>
public class FileOperate : System.Web.UI.Page
...{
protected System.Web.UI.WebControls.TextBox tbContext;
protected System.Web.UI.WebControls.Button btCreate;
protected System.Web.UI.WebControls.Button btWrite;
private void Page_Load(object sender, System.EventArgs e)
...{
if(!this.IsPostBack )
...{
// 在代码中模拟IIS认证帐号
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//在下面的代码段里,代码的具有管理员的权限可以对服务器或本地上已有的文件进行存取,删除等所有权限的操作.
StreamWriter sw = new StreamWriter(Server.MapPath("TestFile.txt"),true);
sw.WriteLine("Liuxibnao");
sw.Close();
File.Delete(Server.MapPath("TestFile.txt"));
//----END
impersonationContext.Undo();
}
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
...{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
...{
this.btWrite.Click += new System.EventHandler(this.btWrite_Click);
this.btCreate.Click += new System.EventHandler(this.btCreate_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void btWrite_Click(object sender, System.EventArgs e)
...{
//此段代码没有模拟ASP.NET,所以他就以本机的ASPNET帐号运行,该帐号属于普通用户组,对文件的权限将受到限制.
//对已有的文件读是正常的.
StreamReader sr = new StreamReader(Server.MapPath("NewCreateText.txt"));
string strLine="";
strLine= sr.ReadToEnd();
sr.Close();
tbContext.Text = strLine;
//但对已有的文件写是会产生异常的.
StreamWriter sw = new StreamWriter(Server.MapPath(""),true);
sw.WriteLine("Hello File System");
sw.Close();
}
private void btCreate_Click(object sender, System.EventArgs e)
...{
//此段代码由于文件是代码自己产生的,所以此段代码拥有对文件的所有操作权限,不需要模拟ASP.NET
FileStream fout = new FileStream(Server.MapPath("Hello.txt"),FileMode.Create,FileAccess.Write);
StreamWriter sw = new StreamWriter(fout);
sw.WriteLine("Hello,world");
sw.Close();
fout.Close();
File.Delete(Server.MapPath("Hello.txt"));
}
}
}