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

.NET Core调用SSRS报告遇NTLM认证未授权错误求解决

在.NET Core中调用SSRS报告的NTLM认证错误修复指南

问题概述

在.NET Core应用中生成SSRS报告时,遭遇NTLM认证异常:

The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM'.

移除凭证、使用BasicHttpSecurityMode.None搭配HttpClientCredentialType.None时程序可正常运行,但业务要求必须为服务添加凭证。尝试设置ProxyCredentialType为Ntlm、替换HttpClientCredentialType为Windows均无效,且.NET Core中找不到.NET Framework方案提及的web.config或配置编辑器。

已尝试的无效操作

  • 设置ProxyCredentialType = HttpProxyCredentialType.Ntlm,仍触发原认证错误
  • 替换HttpClientCredentialType.Ntlm为HttpClientCredentialType.Windows,触发新错误:

System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'

可行修复方案

1. 强制绑定仅使用NTLM认证

在绑定配置中添加ExtendedProtectionPolicy禁用Negotiate(Kerberos回退机制),确保客户端只发送NTLM认证头:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
binding.MaxReceivedMessageSize = 10485760; // 10MB限制

// 关键:禁用Extended Protection,强制使用纯NTLM
binding.Security.Transport.ExtendedProtectionPolicy = new System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy(System.Security.Authentication.ExtendedProtection.ProtectionPolicy.None);

var rsExec = new ReportExecutionServiceSoapClient(binding, new EndpointAddress(SSRSReportExecutionUrl));
// 注意:域环境下替换"."为实际域名,本地账户保留"."
var clientCredentials = new NetworkCredential(SSRSUsername, SSRSPassword, "YOUR-DOMAIN-OR-MACHINE-NAME");

if (rsExec.ClientCredentials != null)
{
    // 调整模拟级别为Delegation(部分场景需要)
    rsExec.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
    rsExec.ClientCredentials.Windows.ClientCredential = clientCredentials;
}

2. 用appsettings.json管理WCF配置(.NET Core友好)

.NET Core支持通过配置文件管理WCF绑定,避免硬编码。在appsettings.json中添加:

{
  "SSRS": {
    "ReportExecutionEndpoint": "http://your-ssrs-server/ReportServer/ReportExecution2005.asmx",
    "BindingSettings": {
      "SecurityMode": "TransportCredentialOnly",
      "ClientCredentialType": "Ntlm",
      "MaxReceivedMessageSize": 10485760
    }
  }
}

然后在代码中读取配置并初始化客户端:

var ssrsConfig = Configuration.GetSection("SSRS").Get<SsrsConfig>();
var binding = new BasicHttpBinding();
binding.Security.Mode = Enum.Parse<BasicHttpSecurityMode>(ssrsConfig.BindingSettings.SecurityMode);
binding.Security.Transport.ClientCredentialType = Enum.Parse<HttpClientCredentialType>(ssrsConfig.BindingSettings.ClientCredentialType);
binding.MaxReceivedMessageSize = ssrsConfig.BindingSettings.MaxReceivedMessageSize;
// 同样添加ExtendedProtectionPolicy设置
binding.Security.Transport.ExtendedProtectionPolicy = new System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy(System.Security.Authentication.ExtendedProtection.ProtectionPolicy.None);

var rsExec = new ReportExecutionServiceSoapClient(binding, new EndpointAddress(ssrsConfig.ReportExecutionEndpoint));
// 凭证设置同方案1

(需定义对应SsrsConfig类来绑定配置)

3. 检查SSRS服务器端配置

确保SSRS服务器的Web服务已正确启用NTLM:

  • 打开IIS管理器,定位到ReportServer站点
  • 进入身份验证模块,启用Windows身份验证
  • 点击Windows身份验证的"提供程序",确保NTLM在列表中且优先级高于Negotiate
  • 打开SSRS配置管理器,进入Web服务URL,确认身份验证设置中已勾选NTLM

4. 本地账户场景的额外处理

如果使用SSRS服务器的本地账户(非域账户):

  • 确保客户端与服务器在同一信任网络
  • 在服务器上禁用UAC远程限制:通过组策略编辑器(gpedit.msc),进入计算机配置>Windows设置>安全设置>本地策略>安全选项,设置本地账户的管理员批准模式为"已禁用"
  • NetworkCredential的域名参数使用服务器的完整机器名,而非"."

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:12:12