Window模拟用户登入

最近在项目中出现一个这样的需求:
在Server服务器上有一个目录(暂时叫Server文件夹吧),在该文件夹上做了权限设置,设置只有Kevin和Tom两个用户有权限对这个文件夹进行操作(上传文件),现在新来了个员工Joms,这个人暂时也需要有对该文件夹上传文件的权限,但是又不想直接给他设置权限,希望能够让他模拟Kevin或者Tom的权限来操作
想了好久,后来公司的老员工想到了这个方法:
现在把代码贴出来大家看看,如果有什么好的方法记的PM我哦!!!
  UpdateFile
{

private string tempPath = string.Empty; // 构造函数
public UpdateFile() { this.tempPath = Environment.GetEnvironmentVariable("WINDIR");
//处理文件夹路径 if (!this.tempPath.Substring(this.tempPath.Length - 1).Equals(@"\")) { this.tempPath = this.tempPath + @"\"; } this.tempPath = this.tempPath + @"TEMP\"; }


     //调用非托管代码CloseHandle用于关闭句柄 [DllImport("kernel32.dll", CharSet=CharSet.Auto)] private static extern bool CloseHandle(IntPtr handle);
      //上传文件方法 public bool UpFile(string fileFrom, string fileTo) { return this.UpFile(fileFrom, fileTo, string.Empty, string.Empty, string.Empty); } public bool UpFile(string fileFrom, string fileTo, string domainName, string userName, string userPassword) { IntPtr phToken = new IntPtr(0); IntPtr duplicateTokenHandle = new IntPtr(0); bool flag = false; try {
         //判断提供的米你登入的帐号,密码为空
if ((userName.Equals(string.Empty) || userPassword.Equals(string.Empty)) || (domainName.Equals(string.Empty) || WindowsIdentity.GetCurrent().Name.ToLower().Equals(userName.ToLower().Trim()))) { File.Copy(fileFrom, fileTo, true); return flag; }
//定义句柄 phToken = IntPtr.Zero; duplicateTokenHandle = IntPtr.Zero;
//LogonUser也是一个非托管代码集中的方法,这中间的phToken就是用帐号登入后的模拟句柄 flag = LogonUser(userName, domainName, userPassword, 2, 0, ref phToken); if (!flag) { return flag; }
//进一步 if (!DuplicateToken(phToken, 2, ref duplicateTokenHandle)) {
//关闭句柄 CloseHandle(phToken); return false; }
//WindowImpersonationContext类是一个用于模拟操作之前的 Windows 用户也就是DuplicateToken用户。 WindowsImpersonationContext context = new WindowsIdentity(duplicateTokenHandle).Impersonate(); File.Copy(fileFrom, fileTo, true);
//完成上传后撤消帐号的模拟登入,恢复为原始标识。 context.Undo(); if (phToken != IntPtr.Zero) { CloseHandle(phToken); } if (duplicateTokenHandle != IntPtr.Zero) { CloseHandle(duplicateTokenHandle); } flag = true; } catch (Exception exception) { throw exception; } return flag; } [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] private static extern bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); [DllImport("advapi32.dll", SetLastError=true)] private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); // Properties public string SystemTempPath { get { return this.tempPath; } }} 希望对大家有帮助!
新加一个测试程序,主要是验证调用了LogonUser和DuplicateToken方法前后,系统显示的"当前登入的用户名"的不同
using System;
using System.Runtime.InteropServices;
using System.Configuration;
using System.ComponentModel;
using System.Diagnostics;
using System.Security.Principal;
namespace DuplicationTokenLogin
{
 /// <summary>
 /// Class1 的摘要说明。
 /// </summary>
 class Class1
 {
  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
   //
   // TODO: 在此处添加代码以启动应用程序
   //

   IntPtr tokenHandle =new IntPtr(0);
   IntPtr DupeHandle = new IntPtr(0);
   string sDemainName = string.Empty;
   string sUserName =string.Empty;
   string sPwd =string.Empty;
   Console.WriteLine("Welcome to the test Environment!");
   Console.Write("Please input the name of Demain which you want to logon:");
   sDemainName =Console.ReadLine();
   Console.Write("Please input your Account which you used to logon the Demain of {0}:",sDemainName);
   sUserName =Console.ReadLine();
   Console.Write("Please input your Password used to logon:");
   sPwd =Console.ReadLine();

   tokenHandle =IntPtr.Zero;
   DupeHandle =IntPtr.Zero;
   //LogonUser的第四个参数传递2表示通过网络验证帐号,第五个参数传递0表示用默认的WindowNT来验证
   bool bLogon = LogonUser(sUserName,sDemainName,sPwd,2,0,ref tokenHandle);
   if(!bLogon)
   {
    Console.WriteLine("When logon have error!");
    return;
   }
   Console.WriteLine("Did LogonUser Succeed:" + (bLogon?"Yes":"No"));
   Console.WriteLine("-----------------------------------------------------------");
   Console.WriteLine("value of WindowNT token is {0}",tokenHandle);
   Console.WriteLine("Before impersonation the user,the Logon UserName is{0}",WindowsIdentity.GetCurrent().Name);

   bool bImpersonation = DuplicateToken(tokenHandle,2,ref DupeHandle);
   if(!bImpersonation)
   {
    Console.WriteLine("模拟用户的时候出现错误!");
    return;
   }
   WindowsImpersonationContext context = new WindowsIdentity(DupeHandle).Impersonate();
   Console.WriteLine("Did ImpersonationUser Secceed:" + (bImpersonation?"Yes":"No"));
   Console.WriteLine("----------------------------------------------------------");
   Console.WriteLine("After ImpersonationUser,the Logon UserName is {0}",WindowsIdentity.GetCurrent().Name);
   context.Undo();
   Console.WriteLine("---------------------------------------------------------");
   Console.WriteLine("After Undo,the UserName is {0}",WindowsIdentity.GetCurrent().Name);

   if(tokenHandle !=IntPtr.Zero)
   {
    CloseHandle(tokenHandle);
   }
   if(DupeHandle !=IntPtr.Zero)
   {
    CloseHandle(DupeHandle);
   }
   Console.WriteLine("the Test is Seccued,and press the key of Enter to end the Test!");
   Console.ReadLine();

  }

  [DllImport("advapi32.dll",SetLastError=true)]
  private static extern bool LogonUser(string lpszUserName,string lpszDemain,string lpszPassword,int dwLogonType,int dwLogonProvider,ref IntPtr phToken);
  [DllImport("advapi32.dll",CharSet =CharSet.Auto,SetLastError=true)]
  private static extern bool DuplicateToken(IntPtr ExistingTokenHandle,int SECURITY_IMPERSONATION_LEVEL,ref IntPtr DuplicatonTokenHandle);
  [DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
  private static extern bool CloseHandle(IntPtr handle);

转载于:https://www.cnblogs.com/zyzhang/archive/2008/08/13/1266645.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值