asp.net 模拟如何与 System.Threading.Task 一起使用?
How does asp.net impersonation work with System.Threading.Task?
我想使用客户端用户的凭据访问数据库。
我的代码:
Task.Run(() =>
{
// Connect to DB.
}
我在 system.web 节点中有带有模拟属性的身份标签:
<identity impersonate="true" />
我在system.web服务器节点中有验证标签:
<validation validateIntegratedModeConfiguration="false" />
我将身份验证设置为 windows:
<authentication mode="Windows" />
我在 iis 中的应用程序上设置了模拟和 windows:
我将应用设置为使用直通:
我已经重启iis了。
我不知道它是如何工作的,或者我完全误解了它。
根据您的评论,您似乎正在 运行ning System.Security.Principal.WindowsIdentity.GetCurrent().Name
任务中,并获取 App Pool 的身份而不是模拟用户的身份。这是一个常见问题(请查看 this question I asked a while back)。
但是,有一个解决方法。如果您仍然希望您的任务 运行 作为模拟用户,您必须在任务 运行s 之前保存当前用户的令牌 并尝试 "re-impersonate" 任务的上下文是这样的:
IntPtr currentUser = WindowsIdentity.GetCurrent().Token; // This token points to the impersonated user
Task.Run(() =>
{
using (WindowsIdentity.Impersonate(token))
{
// Connect to DB.
}
}
这可确保 Using
区块 运行 中的任何内容都在模拟用户的身份下。
周围有这个:
Windows 互操作...
public static class Win32LogonInterop
{
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static WindowsIdentity LogOn(string domain, string userName, string password)
{
IntPtr token = IntPtr.Zero;
if (NativeMethods.LogonUser(userName, domain, password, ConnectionKind.NewCredentials, Provider.Default, out token))
{
return new WindowsIdentity(token);
}
else
{
RaiseError();
return null;
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static void LogOff(WindowsIdentity identity)
{
if (identity != null)
{
if (!NativeMethods.CloseHandle(identity.Token))
RaiseError();
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
private static void RaiseError()
{
int errorCode = Marshal.GetLastWin32Error();
throw new Win32Exception(errorCode);
}
}
internal static class NativeMethods
{
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool LogonUser(
string userName,
string domain,
string password,
ConnectionKind connectionKind,
Provider provider,
out IntPtr token);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr handle);
}
public enum Provider
{
Default = 0,
WindowsNT35 = 1,
WindowsNT40 = 2,
WindowsNT50 = 3
}
public enum SecurityLevel
{
Anonymous = 0,
Identification = 1,
Impersonation = 2,
Delegation = 3
}
public enum ConnectionKind
{
Unknown = 0,
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkClearText = 8,
NewCredentials = 9
}
模仿方法...
private void MyMethod(string domain, string userName, string password)
{
WindowsIdentity _identity = Win32LogonInterop.LogOn(domain, userName, password);
WindowsImpersonationContext impersonation = null;
try
{
impersonation = _identity.Impersonate();
// Stuff that needs impersonation
}
finally
{
if (impersonation != null)
{
impersonation.Undo();
impersonation.Dispose();
}
if (_identity != null)
{
Win32LogonInterop.LogOff(_identity);
}
}
}
我想使用客户端用户的凭据访问数据库。
我的代码:
Task.Run(() =>
{
// Connect to DB.
}
我在 system.web 节点中有带有模拟属性的身份标签:
<identity impersonate="true" />
我在system.web服务器节点中有验证标签:
<validation validateIntegratedModeConfiguration="false" />
我将身份验证设置为 windows:
<authentication mode="Windows" />
我在 iis 中的应用程序上设置了模拟和 windows:
我将应用设置为使用直通:
我已经重启iis了。
我不知道它是如何工作的,或者我完全误解了它。
根据您的评论,您似乎正在 运行ning System.Security.Principal.WindowsIdentity.GetCurrent().Name
任务中,并获取 App Pool 的身份而不是模拟用户的身份。这是一个常见问题(请查看 this question I asked a while back)。
但是,有一个解决方法。如果您仍然希望您的任务 运行 作为模拟用户,您必须在任务 运行s 之前保存当前用户的令牌 并尝试 "re-impersonate" 任务的上下文是这样的:
IntPtr currentUser = WindowsIdentity.GetCurrent().Token; // This token points to the impersonated user
Task.Run(() =>
{
using (WindowsIdentity.Impersonate(token))
{
// Connect to DB.
}
}
这可确保 Using
区块 运行 中的任何内容都在模拟用户的身份下。
周围有这个:
Windows 互操作...
public static class Win32LogonInterop
{
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static WindowsIdentity LogOn(string domain, string userName, string password)
{
IntPtr token = IntPtr.Zero;
if (NativeMethods.LogonUser(userName, domain, password, ConnectionKind.NewCredentials, Provider.Default, out token))
{
return new WindowsIdentity(token);
}
else
{
RaiseError();
return null;
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static void LogOff(WindowsIdentity identity)
{
if (identity != null)
{
if (!NativeMethods.CloseHandle(identity.Token))
RaiseError();
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
private static void RaiseError()
{
int errorCode = Marshal.GetLastWin32Error();
throw new Win32Exception(errorCode);
}
}
internal static class NativeMethods
{
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool LogonUser(
string userName,
string domain,
string password,
ConnectionKind connectionKind,
Provider provider,
out IntPtr token);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr handle);
}
public enum Provider
{
Default = 0,
WindowsNT35 = 1,
WindowsNT40 = 2,
WindowsNT50 = 3
}
public enum SecurityLevel
{
Anonymous = 0,
Identification = 1,
Impersonation = 2,
Delegation = 3
}
public enum ConnectionKind
{
Unknown = 0,
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkClearText = 8,
NewCredentials = 9
}
模仿方法...
private void MyMethod(string domain, string userName, string password)
{
WindowsIdentity _identity = Win32LogonInterop.LogOn(domain, userName, password);
WindowsImpersonationContext impersonation = null;
try
{
impersonation = _identity.Impersonate();
// Stuff that needs impersonation
}
finally
{
if (impersonation != null)
{
impersonation.Undo();
impersonation.Dispose();
}
if (_identity != null)
{
Win32LogonInterop.LogOff(_identity);
}
}
}