我會建議幾件事情要檢查:
您應歸功於你的類(即執行模擬)的完全信任模式的要求,你可以使用
[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