首页 > 解决方案 > 在 asp.net core 中模拟用户

问题描述

我有来自常规 mvc 应用程序的以下代码,它通过模拟用户上传文件

 public class PublicController : Controller
 {
    public const int LOGON32_LOGON_INTERACTIVE = 2;
    public const int LOGON32_PROVIDER_DEFAULT = 0;
    WindowsImpersonationContext impersonationContext;
    [DllImport("advapi32.dll")]
    public static extern int LogonUserA(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int DuplicateToken(IntPtr hToken,
        int impersonationLevel,
        ref IntPtr hNewToken);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool RevertToSelf();
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern bool CloseHandle(IntPtr handle);
    

    public SomeActionMethod(model containing file)
    {
       if (ImpersonateValidUser(userName: "someuserwithpowertoupload", domain: "", password: "somepassword"))
       {
        path = "Somepath";
        file.SaveAs(path);
       }
    }


 private bool ImpersonateValidUser(String userName, String domain, String password)
    {
        WindowsIdentity tempWindowsIdentity;
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;
        if (RevertToSelf())
        {
            if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT, ref token) != 0)
            {
                if (DuplicateToken(token, impersonationLevel: 2, hNewToken: ref tokenDuplicate) != 0)
                {
                    using (tempWindowsIdentity = new WindowsIdentity(tokenDuplicate))
                    {
                        this.impersonationContext = tempWindowsIdentity.Impersonate();
                        if (this.impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }
        }
        if (token != IntPtr.Zero)
        {
            CloseHandle(token);
        }
        if (tokenDuplicate != IntPtr.Zero)
        {
            CloseHandle(tokenDuplicate);
        }
        return false;
    }

这里的问题是 .net 核心中不存在 WindowsImpersonationContext。任何人都可以提供模拟用户的代码片段吗?此处的 Microsoft 文档https://docs.microsoft.com/en-us/dotnet/standard/security/impersonating-and-reverting不是很有帮助。

谢谢你。

标签: asp.net-core

解决方案


从文档

ASP.NET Core 不实现模拟。使用应用程序池或进程标识,应用程序使用应用程序标识运行所有请求。如果应用程序应该代表用户执行操作,请使用WindowsIdentity.RunImpersonatedRunImpersonatedAsync在终端内联中间件中的Startup.Configure.

app.Run(async (context) =>
{
    try
    {
        var user = (WindowsIdentity)context.User.Identity;

        await context.Response
            .WriteAsync($"User: {user.Name}\tState: {user.ImpersonationLevel}\n");

        WindowsIdentity.RunImpersonated(user.AccessToken, () =>
        {
            var impersonatedUser = WindowsIdentity.GetCurrent();
            var message =
                $"User: {impersonatedUser.Name}\t" +
                $"State: {impersonatedUser.ImpersonationLevel}";

            var bytes = Encoding.UTF8.GetBytes(message);
            context.Response.Body.Write(bytes, 0, bytes.Length);
        });
    }
    catch (Exception e)
    {
        await context.Response.WriteAsync(e.ToString());
    }
});

推荐阅读