实例在ASP.NET应用程序中使用身份模拟

本文只描述一些关键点,详细信息请参考文后msdn 文章。    
  有时上传的图片或文件太多,就考虑向网络盘上传图片或文件,这个时候如果还像本地上传图片那样,应用程序就会报错:Could not find a part of the path //ip/filepath
解决这个问题必须先了解asp.net的安全体系,用身份模拟的方法使得读写文件成行。

关键词:身份模拟

 缺省情况下,ASP.NET应用程序以本机的ASPNET帐号运行,该帐号属于普通用户组,权限受到一定的限制,以保障ASP.NET应用程序运行的安全。但是有时需要某个ASP.NET应用程序或者程序中的某段代码执行需要特定权限的操作,比如某个文件的存取,这时就需要给该程序或相应的某段代码赋予某个帐号的权限以执行该操作,这种方法称之为身份模拟(Impersonation)。

 需要设置一个专有的域用户用来执行该操作。在此条件下通常有两种方式:
在ASP.NET应用程序中使用身份模拟Impersonation
1.   配置web.config

<identity impersonate="true" userName="domain/accountname" password="password" />

2.代码中模拟指定的用户帐号更加灵活,只作用于要访问资源的代码段。实例代码参考:

 //模拟帐户
using System.Web.Security;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Configuration;

 public class YourClass
 {
  //模拟帐户信息
  private string ImpersonateDomainName;
  private string ImpersonateAccountName;
  private string ImpersonateAccountPassword;

  public YourClass()
  {
   //构造函数得到模拟帐户信息,从web.config里配置得到
    ImpersonateDomainName=ConfigurationSettings.AppSettings["ImpersonateDomainName"].ToString();
   ImpersonateAccountName=ConfigurationSettings.AppSettings["ImpersonateAccountName"].ToString();
   ImpersonateAccountPassword=ConfigurationSettings.AppSettings["ImpersonateAccountPassword"].ToString();
  }
  #region 模拟身份验证
  public const int LOGON32_LOGON_INTERACTIVE = 2;
  public const int LOGON32_PROVIDER_DEFAULT = 0;

  WindowsImpersonationContext impersonationContext;

  [DllImport("advapi32.dll", CharSet=CharSet.Auto)]
  public static extern int LogonUser(String lpszUserName,
   String lpszDomain,
   String lpszPassword,
   int dwLogonType,
   int dwLogonProvider,
   ref IntPtr phToken);
  [DllImport("advapi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]
  public extern static int DuplicateToken(IntPtr hToken,
   int impersonationLevel, 
   ref IntPtr hNewToken);
  #endregion

  #region 图片
  #region 模拟身份验证
  private bool impersonateValidUser(String userName, String domain, String password)
  {
   WindowsIdentity tempWindowsIdentity;
   IntPtr token = IntPtr.Zero;
   IntPtr tokenDuplicate = IntPtr.Zero;

   if(LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
    LOGON32_PROVIDER_DEFAULT, ref token) != 0)
   {
    if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
    {
     tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
     impersonationContext = tempWindowsIdentity.Impersonate();
     if (impersonationContext != null)
      return true;
     else
      return false;
    }
    else
     return false;
   }
   else
    return false;
  }
  private void undoImpersonation()
  {
   impersonationContext.Undo();
  }
  #endregion
  /// <summary>
  /// 得到指定资源库中所有图片列表
  /// </summary>
  /// <param name="iNo"></param>
  /// <returns></returns>
  public DataTable GetPictureLib(int iNo)
  {
   //返回表 PicLib:iNo,PicName
   try
   {
    if(impersonateValidUser(ImpersonateAccountName, ImpersonateDomainName, ImpersonateAccountPassword))
    {
     //Insert your code that runs under the security context of a specific user here.
     #region 获得图片库
     string SubPath="temp";
     string PicPathV="../picturelib/" + SubPath+"/"+iNo+"/";
     string PicPath=HttpContext.Current.Server.MapPath(PicPathV);
   
     DataTable tb=new DataTable("PicLib");
     tb.Columns.Add("iNo",typeof(System.Int32));
     tb.Columns.Add("PicName",typeof(System.String));


     //是否存在此目录
     if (!Directory.Exists(PicPath))
     {
      return null;
     }

     DirectoryInfo dir = new DirectoryInfo(PicPath);
     FileSystemInfo[] entryies = dir.GetFileSystemInfos();
     FileSystemInfo file;
 
     for (int i=0;i<entryies.Length;i++)
     {
      file=entryies[i];
      //如果是一个文件
      if(file.GetType()==typeof(FileInfo) && (file.Extension.ToLower()==".jpg" || file.Extension.ToLower()==".gif" || file.Extension.ToLower()==".jpeg") )
      {
       DataRow dr=tb.NewRow();
       dr["iNo"]=iNo;
       dr["PicName"]=file.Name;
       tb.Rows.Add(dr);
      }

     }

     #endregion
     undoImpersonation();

     return tb;
    }
    else
    {
     //Your impersonation failed. Therefore, include a fail-safe mechanism here.
     throw new Exception("没有操作资源的权限,请确认管理员域用户权限,IIS或Web.Config配置正确!");
    }

   }

   catch(Exception ex)
   {
    throw(ex);
   }

  }
  /// <summary>
  /// 得到上传文件路经里的文件名
  /// </summary>
  /// <param name="fileName"></param>
  /// <returns></returns>
  private string getFileName(string fileName)
  {
   int position;
   position=fileName.LastIndexOf("//");
   return fileName.Substring(position+1);
  }
  /// <summary>
  /// 得到文件名的扩展名
  /// </summary>
  /// <param name="fileName"></param>
  /// <returns></returns>
  private string getExtendedName(string fileName)
  {
   int position;
   position=fileName.LastIndexOf(".");
   return fileName.Substring(position);
  }
  /// <summary>
  /// 得到数字随机串
  /// </summary>
  /// <returns></returns>
  private string GetNumberRandom()
  {
   int intNum;
   long lngNum;
   string strNum = System.DateTime.Now.ToString("G");
   strNum = strNum.Replace(":","");
   strNum = strNum.Replace("-","");
   strNum = strNum.Replace(" ","");
   strNum = strNum.Replace("/","");
   strNum = strNum.Replace("PM","1");
   strNum = strNum.Replace("AM","0");

   lngNum = long.Parse(strNum);
   System.Random ran = new Random();
   intNum = ran.Next(1,99999);
   ran= null;
   lngNum +=intNum;
   return lngNum.ToString();
  }
  /// <summary>
  /// 上传图片时将数据保存到服务器文件夹里
  /// </summary>
  /// <param name="iNo"></param>
  /// <param name="PicName"></param>
  public void UploadPictureToLib(int iNo,string PicName,System.Web.UI.HtmlControls.HtmlInputFile myFile)
  {
   try
   {
    if(impersonateValidUser(ImpersonateAccountName, ImpersonateDomainName, ImpersonateAccountPassword))
    {
     //Insert your code that runs under the security context of a specific user here.
     #region 上传图片库操作
     string SubPath="temp";
     string PicPathV="../picturelib/" + SubPath+"/"+iNo+"/";
     string PicPath=HttpContext.Current.Server.MapPath(PicPathV);
   
     //是否存在此目录
     if (!Directory.Exists(PicPath))
     {
      Directory.CreateDirectory(PicPath);
     }
   
     //保存上传的图片
     string tmpFileName=getFileName(myFile.PostedFile.FileName);

     if(tmpFileName.IndexOf(".")>0 )
     {
      string tmpExtendedName=getExtendedName(tmpFileName);
      if(tmpExtendedName.ToLower()==".jpg" || tmpExtendedName.ToLower()==".gif" || tmpExtendedName.ToLower()==".jpeg")
      {
       tmpFileName=GetNumberRandom()+tmpExtendedName.ToLower();
       myFile.PostedFile.SaveAs(PicPath+tmpFileName);
      }
      else
       throw new Exception("11104");
     }

     #endregion
     undoImpersonation();
    }
    else
    {
     //Your impersonation failed. Therefore, include a fail-safe mechanism here.
     throw new Exception("没有操作资源的权限,请确认管理员域用户权限,IIS或Web.Config配置正确!");
    }
   }

   catch(Exception ex)
   {
    throw(ex);
   }
  }
#endregion

}

注:iis设置网盘虚拟路径,关键是要把本来默认是本地的虚拟路径连接和目录安全变成域的方式。

1.建虚路径时将路径项手工填入网络地址。

2.完成向导后到属性(properties),主路径(home directory)中选择资源来自(the content for this recources should come from),另一台机器的共享路径 (a share located in another computer),纠正填写网络路径,连接为(connected as),填入你准备的域用户帐号。

3.路径安全性(directory secutity),验证和访问控制(authentication and access control),帐户信息改为你的域用户帐户

 访问以下链接获取更多信息:

http://www.cnblogs.com/drw/articles/17946.html
1. INFO: Implementing Impersonation in an ASP.NET Application
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158&SD=MSKB
2. INFO: ASP.NET Security Overview
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306590
3. ASP.NET Web Application Security
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetwebapplicationsecurity.asp 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值