You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core下实现Windows用户模拟上传文件的代码示例求助

ASP.NET Core Windows身份模拟功能实现方案

前提说明

该实现仅支持在Windows操作系统上运行的ASP.NET Core应用,需先安装NuGet依赖包:System.Security.Principal.Windows

完整代码示例

using Microsoft.AspNetCore.Mvc;
using System.Runtime.InteropServices;
using System.Security.Principal;
using Microsoft.AspNetCore.Http;

public class PublicController : ControllerBase
{
    public const int LOGON32_LOGON_INTERACTIVE = 2;
    public const int LOGON32_PROVIDER_DEFAULT = 0;
    public const int SecurityImpersonation = 2;

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(string lpszUserName,
        string lpszDomain,
        string lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        out IntPtr phToken);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool DuplicateToken(IntPtr hToken,
        int impersonationLevel,
        out IntPtr hNewToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CloseHandle(IntPtr handle);

    [HttpPost]
    public IActionResult UploadFile(IFormFile file)
    {
        IntPtr token = IntPtr.Zero;
        IntPtr duplicateToken = IntPtr.Zero;
        try
        {
            // 调用LogonUser获取用户令牌
            bool logonSuccess = LogonUser(
                userName: "someuserwithpowertoupload",
                domain: "",
                password: "somepassword",
                LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT,
                out token);

            if (!logonSuccess)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, "用户身份验证失败");
            }

            // 复制令牌用于模拟
            bool duplicateSuccess = DuplicateToken(token, SecurityImpersonation, out duplicateToken);
            if (!duplicateSuccess)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, "令牌复制失败");
            }

            // 使用WindowsIdentity.RunImpersonated执行模拟上下文内的操作
            using (var identity = new WindowsIdentity(duplicateToken))
            {
                WindowsIdentity.RunImpersonated(identity.AccessToken, () =>
                {
                    // 模拟上下文内执行文件保存操作
                    var path = "你的目标存储路径";
                    using (var stream = System.IO.File.Create(path))
                    {
                        file.CopyTo(stream);
                    }
                });
            }
            return Ok("文件上传成功");
        }
        catch (Exception ex)
        {
            return StatusCode(StatusCodes.Status500InternalServerError, $"上传失败:{ex.Message}");
        }
        finally
        {
            // 释放令牌资源
            if (token != IntPtr.Zero)
            {
                CloseHandle(token);
            }
            if (duplicateToken != IntPtr.Zero)
            {
                CloseHandle(duplicateToken);
            }
        }
    }
}

关键变更说明

  • .NET Core 3.0+ 移除了WindowsImpersonationContext类,改用WindowsIdentity.RunImpersonated或异步版本RunImpersonatedAsync执行模拟上下文内的逻辑,无需手动维护上下文和执行回滚操作,方法执行完成后会自动恢复原进程身份
  • LogonUser API统一使用Unicode版本LogonUser替代原ANSI版本LogonUserA,避免字符编码问题

注意事项

  • 运行应用的进程身份需要拥有"作为操作系统的一部分"、"允许本地登录"等权限,若部署在IIS中需要对应配置应用池身份的权限
  • 本地用户模拟时domain参数填""或"."即可,域用户需要填写对应的域名
  • 令牌资源必须在finally块中手动释放,避免出现资源泄漏

内容的提问来源于stack exchange,提问作者blue piranha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 01:48:02