WindowsIdentity.RunImpersonated/SafeAccessTokenHandle 在任务/其他线程上

WindowsIdentity.RunImpersonated/SafeAccessTokenHandle on Task/different thread

提问人:Jannick Breunis 提问时间:9/8/2023 最后编辑:Jannick Breunis 更新时间:9/14/2023 访问量:39

问:

在 .NET 6 Web API 上,我创建了一个 AuthorizedUser,它使用 .在本例中,该类由 FileReaderWriterClass 使用。WindowsIdentity.RunImpersonated

public class AuthorizedUser : IDisposable
{
    private readonly SafeAccessTokenHandle safeAccessTokenHandle;

    public AuthorizedUser(IConfiguration configuration)
    {
        string domain = configuration.GetValue<string>("AuthorizedUser:Domain");
        string username = configuration.GetValue<string>("AuthorizedUser:Username");
        string password = configuration.GetValue<string>("AuthorizedUser:Password");

        safeAccessTokenHandle = SafeAccessTokenHandle(domain, username, password);
    }

    private static SafeAccessTokenHandle SafeAccessTokenHandle(string domain, string username, string password)
    {
        bool loginSucces = LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT, out SafeAccessTokenHandle safeAccessTokenHandle);

        if (!loginSucces)
        {
            throw new Exception("Unsuccesful login at SafeAccessTokenHandle()");
        }

        return safeAccessTokenHandle;
    }

    public async Task Run(Task task)
    {
        await WindowsIdentity.RunImpersonatedAsync(safeAccessTokenHandle, () => task);
    }

    public TResult Run<TResult>(Func<TResult> function)
    { 
        return WindowsIdentity.RunImpersonated(safeAccessTokenHandle, () => function());
    }

    public TResult Run<TArg1, TResult>(Func<TArg1, TResult> function, TArg1 arg1)
    {
        return WindowsIdentity.RunImpersonated(safeAccessTokenHandle, () => function(arg1));
    }
}

最后两种方法似乎有效,第一种方法等待任务,则无效。收到错误

对路径“\different-server\file\path.json”的访问被拒绝。

文档指出

为 Windows 线程或进程访问令牌提供安全句柄。

这是否意味着,当执行 ,它在不同的 上,SafeAccessToken 将不起作用?我应该TaskThread

  1. 为此任务的请求创建一个新令牌,而不是使用字段?
  2. 在令牌线程上执行?Task
  3. 不使用任务(我正在使用可以替换为的任务)?File.WriteAllBytesAsyncFile.WriteAllBytes

编辑: 用于检索 SafeAccessTokenHandle 的代码:

//source: https://learn.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.runimpersonated?view=net-7.0
private const int LOGON32_PROVIDER_DEFAULT = 0;
private const int LOGON32_LOGON_INTERACTIVE = 2;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
    int dwLogonType, int dwLogonProvider, out SafeAccessTokenHandle phToken);
C# 多线程 异步 async-await 任务

评论


答:

0赞 Paulo Morgado 9/9/2023 #1

如果要运行异步代码,则应使用 WindowsIdentity.RunImpersonatedAsync 方法

评论

0赞 Jannick Breunis 9/9/2023
谢谢,要用它。但仍然是相同的错误(UnauthorizedAccessException)。
0赞 Paulo Morgado 9/9/2023
当时的令牌是正确的吗?
1赞 Charlieface 9/10/2023
@JannickBreunis 请使用该方法显示您当前的代码WindowsIdentity.RunImpersonatedAsync
0赞 Jannick Breunis 9/14/2023
在帖子中更改了它。但它只是 RunImpersonated 更改为 RunImpersonatedAsync?