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

如何在IIS托管的ASP.Net Core应用中读取认证网络共享/UNC路径文件?

ASP.NET Core 读取Windows网络共享(UNC)文件的解决方案

问题描述

我有一个Windows FSX的UNC/网络共享,希望我的ASP.NET Core Web应用读取该共享中的文件。之前尝试使用SimpleImpersonation NuGet包,但该包已被弃用。请问在.NET Core中如何正确读取网络共享文件?以下是我之前的尝试代码:

var credentials = new UserCredentials(uncPath, userName, password);
var result = WindowsIdentity.RunImpersonated(credentials, () => {
      return _fileSystem.File.ReadAllText($"\\\\{uncPath}\\test.txt");
});

可行解决方案

方法1:使用.NET内置身份模拟(WindowsIdentity.RunImpersonated)

SimpleImpersonation弃用后,可直接调用Windows API获取用户访问令牌,配合WindowsIdentity.RunImpersonated实现身份模拟。需引入System.Security.Principal和System.Runtime.InteropServices命名空间。

示例代码:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Principal;

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

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hObject);

    private const int LOGON32_LOGON_INTERACTIVE = 2;
    private const int LOGON32_PROVIDER_DEFAULT = 0;

    public string ReadNetworkFile(string uncPath, string domain, string username, string password)
    {
        if (!LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out IntPtr tokenHandle))
        {
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        }

        try
        {
            using var safeTokenHandle = new SafeAccessTokenHandle(tokenHandle);
            return WindowsIdentity.RunImpersonated(safeTokenHandle, () =>
            {
                return File.ReadAllText(Path.Combine(uncPath, "test.txt"));
            });
        }
        finally
        {
            CloseHandle(tokenHandle);
        }
    }
}

注意:

  • 本地账号传机器名作为domain参数,域账号传域名
  • 确保应用运行账号拥有调用LogonUser的权限,可通过本地安全策略调整"允许本地登录"权限

方法2:配置应用池身份(IIS部署场景)

若为IIS部署的ASP.NET Core应用,可直接将应用池身份设为拥有网络共享访问权限的账号,无需手动模拟:

  1. 打开IIS管理器,找到目标应用池
  2. 右键选择"高级设置",修改"标识"为指定账号
  3. 确保该账号对目标网络共享拥有读取权限
  4. 直接通过UNC路径读取文件:
var content = File.ReadAllText(@"\\server\share\test.txt");

方法3:临时挂载网络共享(适合一次性操作)

通过命令行挂载网络共享为本地驱动器,读取后再卸载。注意此方法存在密码暴露风险,不推荐生产环境使用:

using System.Diagnostics;

public string ReadFileViaMount(string uncPath, string driveLetter, string username, string password)
{
    // 挂载共享
    var processStartInfo = new ProcessStartInfo
    {
        FileName = "net",
        Arguments = $"use {driveLetter}: {uncPath} /user:{username} {password}",
        WindowStyle = ProcessWindowStyle.Hidden,
        CreateNoWindow = true
    };

    using var process = Process.Start(processStartInfo);
    process.WaitForExit();

    if (process.ExitCode != 0)
    {
        throw new InvalidOperationException("挂载网络共享失败");
    }

    try
    {
        return File.ReadAllText($"{driveLetter}:\\test.txt");
    }
    finally
    {
        // 卸载共享
        var unmountProcess = Process.Start(new ProcessStartInfo
        {
            FileName = "net",
            Arguments = $"use {driveLetter}: /delete",
            WindowStyle = ProcessWindowStyle.Hidden,
            CreateNoWindow = true
        });
        unmountProcess?.WaitForExit();
    }
}

常见注意事项

  • 确保网络共享权限设置正确:目标账号需同时拥有共享文件夹和内部文件的读取权限
  • Docker部署的Windows容器,需确保容器有权限访问主机或局域网的网络共享
  • 避免硬编码账号密码,建议用配置文件或密钥管理服务存储敏感信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:11:20