.NET 6无密码模拟域用户:从.NET Framework 4.8迁移的实现难题
.NET 6 Web应用模拟域用户问题及尝试过程
我有一个.NET 6 Web应用,需要模拟当前域用户以代表其执行操作。用户通过OAuth认证,因此仅能从ClaimsIdentity中提取用户的UPN。我在.NET Framework 4.8中已有可行方案,但无法在.NET 6中实现相同功能,以下是具体配置及尝试过程:
.NET Framework 4.8可行方案
在Web服务器上配置Claims to Windows Token服务(c2wts),允许应用池身份模拟用户,并通过本地策略编辑器为应用池身份授予以下权限:
- 作为操作系统的一部分(Act as part of the operating system)
- 允许本地登录(Allow log on locally)
- 生成安全审核(Generate security audits)
- 身份验证后模拟客户端(Impersonate a client after authentication)
- 作为服务登录(Log on as a service)
基于该配置,使用.NET Framework 4.8可通过以下代码模拟用户:
void WorksWithFramework_4_8(string userUpn) { var windowsIdentity = S4UClient.UpnLogon(userUpn); WindowsImpersonationContext context = windowsIdentity.Impersonate(); // 执行操作... context.Undo(); }
.NET 6尝试1:调用S4UClient.UpnLogon
调用S4UClient.UpnLogon时触发异常:
'Microsoft.IdentityModel.WindowsTokenService.S4UClient'的类型初始化程序引发异常。
内部异常:
FileNotFoundException: 未能加载文件或程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”。系统找不到指定的文件。
已尝试但无效的操作:
- 添加
System.ServiceModel.Primitives包引用 - 卸载并重新安装框架
.NET 6尝试2:使用WindowsIdentity.RunImpersonated
测试代码如下:
static void RunImpersonatedTest(string upn) { WindowsIdentity identity = new WindowsIdentity(upn); WindowsIdentity.RunImpersonated(identity.AccessToken, () => { // 输出预期用户名 Console.WriteLine(WindowsIdentity.GetCurrent().Name); // 尝试访问需权限的资源时失败 foreach (var file in Directory.EnumerateFiles(@"\\SOME-MACHINE\C$\tmp")) { Console.WriteLine(file); } }); }
执行需要权限的操作时,出现访问拒绝错误或以下异常:
未提供所需的模拟级别,或者提供的模拟级别无效。(HRESULT异常: 0x80070542)
内容的提问来源于stack exchange,提问作者Paolo Tedesco
相关产品推荐
相关产品推荐

