[英]How can I temporarily impersonate a user to open a file?
I would like to temporarily impersonate a domain user account to read in a file on a network drive from an ASP.NET site. 我想暂时模拟一个域用户帐户,以从ASP.NET站点读取网络驱动器上的文件。
I would rather not set up impersonation for the entire site or set up a mapped drive on the server. 我宁愿不为整个站点设置模拟或在服务器上设置映射驱动器。
I ended up using code from Michiel van Otegem: WindowsImpersonationContext made easy and added an implementation of IDisposable. 我最终使用了Michiel van Otegem的代码:WindowsImpersonationContext变得简单,并添加了IDisposable的实现。 I found this in another question about impersonation in ASP.NET . 我在另一个有关ASP.NET中模拟的问题中发现了这一点。
Usage: 用法:
using (WindowsImpersonationContextFacade impersonationContext
= new WindowsImpersonationContextFacade(
Settings.Default.ImpersonationDomain,
Settings.Default.ImpersonationUser,
Settings.Default.ImpersonationPass))
{
transactions = TransactionLoader.Load(filePath);
}
Code: 码:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.ComponentModel;
namespace MyNamespace
{
public class WindowsImpersonationContextFacade : IDisposable
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain,
String lpszPassword, int dwLogonType, int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
private const int LOGON32_PROVIDER_DEFAULT = 0;
private const int LOGON32_LOGON_INTERACTIVE = 2;
private string m_Domain;
private string m_Password;
private string m_Username;
private IntPtr m_Token;
private WindowsImpersonationContext m_Context = null;
protected bool IsInContext
{
get { return m_Context != null; }
}
public WindowsImpersonationContextFacade(string domain, string username, string password)
{
m_Domain = domain;
m_Username = username;
m_Password = password;
Enter();
}
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
private void Enter()
{
if (this.IsInContext) return;
m_Token = IntPtr.Zero;
bool logonSuccessfull = LogonUser(
m_Username,
m_Domain,
m_Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref m_Token);
if (logonSuccessfull == false)
{
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
WindowsIdentity identity = new WindowsIdentity(m_Token);
m_Context = identity.Impersonate();
}
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
private void Leave()
{
if (this.IsInContext == false) return;
m_Context.Undo();
if (m_Token != IntPtr.Zero) CloseHandle(m_Token);
m_Context = null;
}
public void Dispose()
{
Leave();
}
}
}
Actually, the process is quite easy, you can use code like this; 实际上,该过程很容易,您可以使用如下代码;
using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
// Start impersonating
ctx = winId.Impersonate();
// Now impersonating
// Access resources using the identity of the authenticated user
}
// Prevent exceptions from propagating
catch
{
}
finally
{
// Revert impersonation
if (ctx != null)
ctx.Undo();
}
// Back to running under the default ASP.NET process identity
Your code goes in the "Now impersonating" section. 您的代码在“现在模拟”部分中。 the KEY is the finally block, this is VERY important. KEY是finally块,这非常重要。 You can view this MSDN article for full details on how this works. 您可以查看此MSDN文章,以获取有关其工作原理的完整详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.