.NET Core
.NET Core也支持用PInvoke来调用操作系统底层的Win32函数
首先要在项目中下载Nuget包:System.Security.Principal.Windows
代码加注释:
using System; using System.IO; using System.Runtime.InteropServices; using System.Security.Principal; namespace NetCorePrincipal { public class WindowsLogin : IDisposable { protected const int LOGON32_PROVIDER_DEFAULT = 0; protected const int LOGON32_LOGON_INTERACTIVE = 2; public WindowsIdentity Identity = null; protected IntPtr m_accessToken; [DllImport("advapi32.dll", SetLastError = true)] private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private extern static bool CloseHandle(IntPtr handle); // AccessToken ==> this.Identity.AccessToken //public Microsoft.Win32.SafeHandles.SafeAccessTokenHandle AT //{ // get // { // var at = new Microsoft.Win32.SafeHandles.SafeAccessTokenHandle(this.m_accessToken); // return at; // } //} public WindowsLogin(string username, string domain, string password) { Login(username, domain, password); } public void Login(string username, string domain, string password) { if (this.Identity != null) { this.Identity.Dispose(); this.Identity = null; } try { this.m_accessToken = new IntPtr(0); Logout(); this.m_accessToken = IntPtr.Zero; bool logonSuccessfull = LogonUser( username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref this.m_accessToken); if (!logonSuccessfull) { int error = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(error); } Identity = new WindowsIdentity(this.m_accessToken); } catch { throw; } } public void Logout() { if (this.m_accessToken != IntPtr.Zero) CloseHandle(m_accessToken); this.m_accessToken = IntPtr.Zero; if (this.Identity != null) { this.Identity.Dispose(); this.Identity = null; } } // End Sub Logout public void Dispose() { Logout(); } // End Sub Dispose } // End Class WindowsLogin class Program { static void Main(string[] args) { Console.WriteLine($"Current user is : {WindowsIdentity.GetCurrent().Name}"); using (WindowsLogin wi = new WindowsLogin("uid", "serverdomain", "pwd")) { WindowsIdentity.RunImpersonated(wi.Identity.AccessToken, () => { Console.WriteLine($"Current user is : {WindowsIdentity.GetCurrent().Name}"); //假定要操作的文件路径是10.0.250.11上的d:\txt.txt文件可以这样操作 FileInfo file = new FileInfo(@"\\10.0.250.11\d$\txt.txt"); //想做什么操作就可以做了 }); } Console.WriteLine($"Current user is : {WindowsIdentity.GetCurrent().Name}"); Console.WriteLine("Press any key to quit..."); Console.ReadKey(); } } }
.NET Framework
代码加注释:
using System; using System.IO; using System.Runtime.InteropServices; using System.Security.Principal; namespace NetFrameworkPrincipal { public class WindowsLogin : IDisposable { protected const int LOGON32_PROVIDER_DEFAULT = 0; protected const int LOGON32_LOGON_INTERACTIVE = 2; public WindowsIdentity Identity = null; protected IntPtr m_accessToken; [DllImport("advapi32.dll", SetLastError = true)] private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private extern static bool CloseHandle(IntPtr handle); // AccessToken ==> this.Identity.AccessToken //public Microsoft.Win32.SafeHandles.SafeAccessTokenHandle AT //{ // get // { // var at = new Microsoft.Win32.SafeHandles.SafeAccessTokenHandle(this.m_accessToken); // return at; // } //} public WindowsLogin(string username, string domain, string password) { Login(username, domain, password); } public void Login(string username, string domain, string password) { if (this.Identity != null) { this.Identity.Dispose(); this.Identity = null; } try { this.m_accessToken = new IntPtr(0); Logout(); this.m_accessToken = IntPtr.Zero; bool logonSuccessfull = LogonUser( username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref this.m_accessToken); if (!logonSuccessfull) { int error = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(error); } Identity = new WindowsIdentity(this.m_accessToken); } catch { throw; } } public void Logout() { if (this.m_accessToken != IntPtr.Zero) CloseHandle(m_accessToken); this.m_accessToken = IntPtr.Zero; if (this.Identity != null) { this.Identity.Dispose(); this.Identity = null; } } // End Sub Logout public void Dispose() { Logout(); } // End Sub Dispose } // End Class WindowsLogin class Program { static void Main(string[] args) { Console.WriteLine($"Current user is : {WindowsIdentity.GetCurrent().Name}"); using (WindowsLogin wi = new WindowsLogin("uid", "serverdomain", "pwd")) { //WindowsIdentity.RunImpersonated(wi.Identity.AccessToken, () => //{ // //假定要操作的文件路径是10.0.250.11上的d:\txt.txt文件可以这样操作 // FileInfo file = new FileInfo(@"\\10.0.250.11\d$\txt.txt"); // //想做什么操作就可以做了 //}); using (wi.Identity.Impersonate()) { Console.WriteLine($"Current user is : {WindowsIdentity.GetCurrent().Name}"); //假定要操作的文件路径是10.0.250.11上的d:\txt.txt文件可以这样操作 FileInfo file = new FileInfo(@"\\10.0.250.11\d$\txt.txt"); //想做什么操作就可以做了 } } Console.WriteLine($"Current user is : {WindowsIdentity.GetCurrent().Name}"); Console.WriteLine("Press any key to quit..."); Console.ReadKey(); } } }
模拟域帐户之后,就有了模拟用户的权限,这里千万要注意安全!