.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 }