我会建议几件事情要检查:
您应归功于你的类(即执行模拟)的完全信任模式的要求,你可以使用
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
此外,你应该导入“advapi32.dl l“和LogonUser稍后使用。
- 最后,您应该得到一个安全的令牌句柄(继承自SafeHandleZeroOrMinusOneIsInvalid,它为Win32安全句柄实现提供了一个基类,其中0或-1的值表示无效句柄)。 (使用LOGON32_LOGON_INTERACTIVE *由于批处理将无法正常工作*)
在这个你应该调用它像这样
LogonUser(userName, domainName, password, 2, 0, out safeTokenHandle);
得到一个句柄之后,你应该使用它执行任何操作:
WindowsIdentity impid = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
得到它后,封装你的行动:
using (WindowsImpersonationContext imp = impid.Impersonate())
{
// myActions
}
这应该使您能够正确地做到这一点,并检测它是如何发生的。
我现在已经尝试在ASP.NET应用程序中执行此操作并成功完成此操作。以下是MVC应用程序控制器的工作代码:
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Web.Mvc;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
namespace StackOimpersonationExample.Controllers
{
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class HomeController : Controller
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out TokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
public ActionResult Index()
{
ViewBag.Message = "This line contains status info.";
#region ImpersonateTestUserAndWriteToRegistry
try
{
const string domainName = "W8CP";
const string userName = "testadmin";
const string password = "sxt";
TokenHandle tokenHandle;
bool returnValue = LogonUser(userName, domainName, password, 2, 0, out tokenHandle);
if (returnValue == false)
{
int retVal = Marshal.GetLastWin32Error();
ViewBag.Message = String.Format("Failed logon: {0}", retVal);
throw new System.ComponentModel.Win32Exception(retVal);
}
using (tokenHandle)
{
ViewBag.Message = "Logon successful!";
var newId = new WindowsIdentity(tokenHandle.DangerousGetHandle());
using (newId.Impersonate())
{
RegistryKey parentKey = Registry.LocalMachine;
RegistryKey softwareKey = parentKey.OpenSubKey("SOFTWARE", true);
if (softwareKey != null)
{
RegistryKey subKey = softwareKey.CreateSubKey("StackAnswer");
subKey.SetValue("CreatedAs", WindowsIdentity.GetCurrent().Name, RegistryValueKind.String);
subKey.SetValue("Website", "http://codecentral.org", RegistryValueKind.String);
subKey.SetValue("Email", "[email protected]", RegistryValueKind.String);
}
}
}
}
catch (Exception ex)
{
ViewBag.Message += String.Format(" Exception: " + ex.Message);
}
#endregion
return View();
}
}
public sealed class TokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private TokenHandle(): base(true){}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
}
如果您提到您正在运行这些测试的操作系统,它可能有助于讨论。我的猜测是你最近在做什么,而且一些紧缩的安全规则正在让你失望。 – 2011-04-07 20:14:10
由于该应用程序已经在本地管理员下运行,您是否已考虑在创建注册表项之前恢复该身份? – 2011-04-07 20:23:42
这个应用程序是网络,并从iis运行它? – Mhmd 2011-04-11 21:45:15