我正在尝试使用本地窗口用户凭据运行winform应用程序,为此,我正在使用impersonation
的以下类,
public class Impersonation
{
/// <summary>
/// Impersonate given logon information.
/// </summary>
/// <param name="logon">Windows logon name.</param>
/// <param name="password">password</param>
/// <param name="domain">domain name</param>
/// <returns></returns>
public static bool Impersonate(string logon, string password, string domain)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (LogonUser(logon, 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 (null != impersonationContext) return true;
}
}
return false;
}
/// <summary>
/// Unimpersonate.
/// </summary>
public static void UnImpersonate()
{
impersonationContext.Undo();
}
[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 = CharSet.Auto, SetLastError = true)]
public extern static int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 4;
private const int LOGON32_PROVIDER_DEFAULT = 0;
private static WindowsImpersonationContext impersonationContext;
}
现在这是'winform`启动代码的代码,
static class Program
{
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string userName = Microsoft.VisualBasic.Interaction.InputBox("Enter User Name", "User Name");
string password = Microsoft.VisualBasic.Interaction.InputBox("Enter Password", "Password");
if (!Impersonation.Impersonate(userName, password, Environment.MachineName))
{
MessageBox.Show("Login failed.");
return;
}
Application.Run(new Form1());
Impersonation.UnImpersonate();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.ToString());
}
}
}
现在,当我通过本地窗口用户的凭据时,登录成功,并且在加载form
时,我会出错,
System.Security.SecurityException:'不允许请求的注册表访问。'
这是完整的堆栈跟踪,
System.ThrowHelper.ThrowSecurityException(ExceptionResource资源)上的在Microsoft.Win32.RegistryKey.OpenSubKey(字符串名称,可写布尔值) 在Microsoft.Win32.RegistryKey.OpenSubKey(字符串名称) 在System.Windows.Forms.LinkUtilities.GetIEColor(字符串名称) 在System.Windows.Forms.LinkUtilities.get_IELinkColor() 在System.Windows.Forms.LinkLabel.get_LinkColor() 在System.Windows.Forms.LinkLabel.OnPaint(PaintEventArgs e) 在System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,Int16层) 在System.Windows.Forms.Control.WmPaint(Message&m) 在System.Windows.Forms.Control.WndProc(Message&m) 在System.Windows.Forms.Label.WndProc(Message&m) 在System.Windows.Forms.LinkLabel.WndProc(Message&msg) 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)
可能是什么原因?
答案 0 :(得分:2)
如果您尝试访问另一个用户的注册表配置单元,我想您会发现您需要成为管理员或LocalSystem帐户。
您可以在LoadUserProfileA function Win32 Api
的底部找到一小段信息。从Windows XP Service Pack 2(SP2)和Windows Server 2003开始, 呼叫者必须是管理员或LocalSystem帐户。 是 不足以使呼叫者仅冒充管理员 或LocalSystem帐户。
注意 :(这是推测性的),但是,您可以启动一个新进程(在管理员凭据下)以加载配置文件并访问注册表