SSRS ReportViewer使用域机器账户访问报表返回401未授权错误求解
问题描述
现有架构
- DB-Server:运行SQL Server 2019,操作系统为Windows 2019
- SSRS-Server:运行SSRS 2019,操作系统为Windows 2019
- Web-Server:运行IIS v10,操作系统为Windows 2019
所有服务器均处于同一个域下,渲染报表的ASP.NET应用使用rsweb:ReportViewer控件实现报表展示。
需求
需要通过机器级账户从ASP.NET应用访问SSRS报表。
当前报错
请求失败,HTTP状态码401: Unauthorized(未授权)
已尝试的排查操作
- 已将Web-Server的机器账户添加到SSRS中,授予了站点设置、文件夹、报表全层级权限,目前先确保能跑通后续再收窄权限,预期所有从Web-Server发往SSRS-Server的访问请求都能被放行。

- 已将应用程序池的标识修改为LocalSystem,虽然违反最小权限原则,但目前仅作为POC验证,也尝试过修改为NetworkService。

- 已调整Web.config配置,尝试过开启身份模拟但未成功,可能是未搭配其他配置生效。当认证模式设为Windows时,ASP.NET使用的Windows身份为
NT AUTHORITY\IUSR,移除该配置后身份变为NT AUTHORITY\NETWORK SERVICE,理论上NETWORK SERVICE账户应该有权限,但依然返回401错误。
- 已修改rsreportserver.config配置文件,路径为
C:\Program Files\Microsoft SQL Server Reporting Services\SSRS\ReportServer\rsreportserver.config
- ASP.NET ReportViewer的配置代码如下:
ReportViewer1.ServerReport.ReportPath = rc.report_ssrs_path; ReportViewer1.ServerReport.ReportServerUrl = new System.Uri(rc.report_ssrs_url); SqlConnectionStringBuilder conString = new Database().conBuilder; List<ReportParameter> parameters = new List<ReportParameter>(); parameters.Add(new ReportParameter("ConString", conString.ConnectionString)); ReportViewer1.ServerReport.SetParameters(parameters); DataSourceCredentials dsc = new DataSourceCredentials(); dsc.Name = ReportViewer1.ServerReport.GetDataSources()[0].Name; dsc.UserId = conString.UserID; dsc.Password = conString.Password; ReportViewer1.ServerReport.SetDataSourceCredentials(new DataSourceCredentials[] { dsc }); ReportViewer1.ShowCredentialPrompts = false; ReportViewer1.ServerReport.Refresh();
解决方案
- 补充ReportViewer的SSRS服务凭证配置
你当前的代码只配置了报表数据源的访问凭证,没有指定访问SSRS服务本身的凭证,ReportViewer默认不会主动传递应用程序池的身份凭证到SSRS服务,需要手动补充配置:
// 补充这一行,使用应用程序池的默认身份凭证访问SSRS ReportViewer1.ServerReport.ReportServerCredentials.NetworkCredentials = System.Net.CredentialCache.DefaultNetworkCredentials;
如果DefaultNetworkCredentials不生效,可以自定义实现IReportServerCredentials接口,显式返回对应机器账户的凭证。
- 配置Kerberos双跳权限
同域跨服务器访问出现401,绝大多数情况是Kerberos双跳配置缺失:
- 如果SSRS服务使用域账户运行,需要在域控制器上为该账户注册
HTTP/SSRS-Server域名、HTTP/SSRS-Server全称域名两个SPN;如果SSRS使用LocalSystem/NetworkService运行,SPN会自动生成无需手动注册。 - 在AD属性中打开Web-Server的计算机账户配置,开启「信任此计算机来委派指定服务」,选择SSRS服务对应的HTTP服务条目即可。
- 核对SSRS权限配置
确认你添加的Web-Server机器账户格式正确,必须为域名\Web服务器计算机名$(末尾的$符号不能省略),同时检查:
- 站点设置-安全中该账户被授予「系统用户」权限
- 对应报表所在文件夹的权限配置中,该账户被授予「浏览」及以上权限
- 修正Web.config配置
修改system.web节点配置如下:
<authentication mode="Windows" /> <identity impersonate="false" />
关闭身份模拟后,应用才会使用应用程序池的身份向外发起请求,而不是继承前端访问用户的身份。
内容的提问来源于stack exchange,提问作者spyder1329
相关产品推荐
相关产品推荐

