.Net 中身分模擬的作法

.Net 中身分模擬的作法

很多時候,在程式設中因為需要存取某些資源,而本身執行的權限又不足夠,導致程式無法存取這些資源.
尤其像ASP.Net這類程式,因為安全性考量,通常不會使用權限太大的帳號作為執行帳號,但有時候又需要存取特定權限的資源,譬如說網路上的某個Share Folder.
這時候下面這段 Code的用處就很大了,可以暫時將身分切換到某個角色用此角色的權限存取資源

程式如下

    1 using System;

    2 using System.IO;

    3 using System.Runtime.InteropServices;

    4 using System.Security.Principal;

    5 using Welltake.Security.Cryptography.Specialized;

    6 using Welltake.ESO.WebSite.CustomerPortal;

    7

    8 namespace ESOWebPortal.Pages.Report

    9 {

   10     [WebSiteFunctionPermissionSecurity(System.Security.Permissions.SecurityAction.Demand, Function = WebSiteFunctionTypes.Report)]

   11 public partial class Report_DownloadFile : BasePage

   12     {

   13         [DllImport("advapi32.dll", SetLastError = true)]

   14 public static extern bool LogonUser(

   15 string lpszUsername,

   16 string lpszDomain,

   17 string lpszPassword,

   18 int dwLogonType,

   19 int dwLogonProvider,

   20 ref IntPtr phToken);

   21

   22 //登出

   23         [DllImport("kernel32.dll")]

   24 public extern static bool CloseHandle(IntPtr hToken);

   25

   26 protected void Page_Load(object sender, EventArgs e)

   27         {

   28 if (!IsPostBack)

   29             {

   30 IntPtr tokenHandle = new IntPtr(0);               

   31                 tokenHandle = IntPtr.Zero;

   32

   33 try

   34                 {

   35 string UserName = "xxx";

   36 string Pw = "xxx";

   37 string MachineName = "xxx";

   38 string domainName = "xxx";

   39

   40

   41 const int LOGON32_PROVIDER_DEFAULT = 0;

   42 const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

   43

   44 bool returnValue = LogonUser(UserName, domainName, Pw,

   45                     LOGON32_LOGON_NEW_CREDENTIALS,

   46                     LOGON32_PROVIDER_DEFAULT,

   47 ref tokenHandle);

   48

   49 WindowsIdentity w = new WindowsIdentity(tokenHandle);

   50                     w.Impersonate();

   51 if (false == returnValue)

   52                     {

   53 throw new Exception("Login Fail");

   54                     }

   55

   56 string fileName = @"\\" + MachineName + @"\ShareFolder\test.xls";

   57 if (File.Exists(fileName))

   58                     {

   59 FileInfo fi = new FileInfo(fileName);

   60

   61                         Response.ClearContent();

   62                         Response.ClearHeaders();

   63                         Response.Clear();

   64

   65                         Response.AddHeader("Content-disposition", "attachment; filename=test.xls");

   66                         Response.ContentType = "application/octet-stream";

   67                         Response.WriteFile(fi.FullName, 0, fi.Length);

   68                         Response.Flush();

   69                         Response.End();

   70                     }

   71                 }

   72 finally

   73                 {

   74 if (tokenHandle != IntPtr.Zero)

   75                     {

   76                         CloseHandle(tokenHandle);

   77                     }

   78                 }

   79             }

   80         }

   81

   82 }