IIS部署C#代码远程访问Windows Server 2016遇未授权访问异常
IIS部署C#代码远程连接Windows Server 2016权限问题解决
问题详情
本地Visual Studio运行代码可正常远程连接Windows Server 2016,但部署到IIS后触发UnauthorizedAccessException异常,堆栈跟踪如下:
System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Management.ManagementScope.InitializeGuts(Object o)
at System.Management.ManagementScope.Initialize()
at System.Management.ManagementObjectSearcher.Initialize()
at System.Management.ManagementObjectSearcher.Get()
使用的代码片段:
ConnectionOptions connectoptions = new ConnectionOptions(); //connectoptions.Impersonation = ImpersonationLevel.Impersonate; connectoptions.Username = username; connectoptions.Password = password; //IP Address of the remote machine ManagementScope scope = new ManagementScope(@"\\" + ip + @"\root\cimv2"); scope.Options = connectoptions; //WMI query to be executed on the remote machine SelectQuery query = new SelectQuery("select * from Win32_Service where name = '" + serviceName + "'"); using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query)) { ManagementObjectCollection collection = searcher.Get(); Console.WriteLine("Logged in"); foreach (ManagementObject service in collection) { Console.WriteLine(service); } }
解决步骤
1. 完善WMI连接配置
代码中注释掉的Impersonation设置是权限不足的核心原因之一,取消注释并补充验证配置:
ConnectionOptions connectoptions = new ConnectionOptions(); connectoptions.Impersonation = ImpersonationLevel.Impersonate; // 启用身份模拟 connectoptions.Authentication = AuthenticationLevel.PacketPrivacy; // 提升连接安全性 connectoptions.Username = username; connectoptions.Password = password;
2. 配置IIS应用池身份
- 打开IIS管理器,找到对应应用的应用池,进入高级设置
- 将标识改为拥有远程WMI访问权限的账号(推荐域账号或目标服务器的本地管理员账号,避免使用默认的ApplicationPoolIdentity)
- 确保该账号在目标Windows Server 2016上拥有以下权限:
- 打开目标服务器的
计算机管理→服务和应用程序→WMI控制,右键选择属性 - 切换到安全标签,定位
root\cimv2节点,添加账号并赋予启用账户和远程启用权限 - 确保账号具备查询目标服务器服务的权限(通常管理员权限即可满足)
- 打开目标服务器的
3. 检查目标服务器防火墙与服务状态
- 在目标服务器的Windows防火墙中,启用
Windows Management Instrumentation (WMI)的入站规则 - 确认目标服务器的
Windows Management Instrumentation服务处于运行状态
4. 修复代码注入风险(额外优化)
当前代码直接拼接serviceName到WQL查询,存在注入漏洞,改用参数化查询:
SelectQuery query = new SelectQuery("select * from Win32_Service where name = @ServiceName"); query.Parameters.Add(new ManagementNamedValue("ServiceName", serviceName));
内容的提问来源于stack exchange,提问作者Redi
相关产品推荐
相关产品推荐

