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

Linux下.NET Core 8调用Windows服务NTLM认证401问题排查

问题:Linux环境下HttpClient通过CNTLM代理请求返回401未授权

配置代码

HttpClient注册代码

services.AddHttpClient("WarehousesHttpClient", httpClient =>
{
    httpClient.BaseAddress = new Uri(WarehouseBaseAddress);
    httpClient.Timeout = TimeSpan.FromHours(3);
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
    return new HttpClientHandler()
    {
        Proxy = new WebProxy("http://127.0.0.1:3128"),//CNTLM local Proxy address
        UseProxy = true,
        Credentials = new NetworkCredential("WarehousesUsername", "WarehousesPassword", "WarehousesDomain")
    };
});

(注:原代码中WarehousesPassword后缺少闭合引号,属于笔误,需修正)

请求发送代码

using HttpClient client = _httpClientFactory.CreateClient("WarehousesHttpClient");
HttpRequestMessage message = new HttpRequestMessage
{
    RequestUri = new Uri("ProductsEndpoint", UriKind.Relative),
    Method = HttpMethod.Get
};
message.Headers.Add("Connection", "keep-alive");
HttpResponseMessage productsResponse = await client.SendAsync(message);

问题现象

本地Windows机器运行正常,部署到Linux服务器后返回401 Unauthorized,响应头信息:

Code: Unauthorized, Content: , Headers: Server: Microsoft-HTTPAPI/2.0,WWW-Authenticate: NTLM,Date: Fri, 25 Apr 2025 12:12:11 GMT,Connection: close

已尝试的操作:移除Handler中的Credentials、仅使用凭据不通过代理、设置AppContext.SetSwitch("System.Net.Security.UseManagedNtlm", true),均无效果。


可能的原因及解决方案

1. 代理凭据设置位置错误

当前代码将凭据设置在HttpClientHandler.Credentials,这是目标服务器的认证凭据,而非代理的认证凭据。Linux环境下需将凭据直接绑定到WebProxy对象:

services.AddHttpClient("WarehousesHttpClient", httpClient =>
{
    httpClient.BaseAddress = new Uri(WarehouseBaseAddress);
    httpClient.Timeout = TimeSpan.FromHours(3);
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
    var proxy = new WebProxy("http://127.0.0.1:3128")
    {
        // 将凭据设置到Proxy对象,而非Handler
        Credentials = new NetworkCredential("WarehousesUsername", "WarehousesPassword", "WarehousesDomain")
    };
    return new HttpClientHandler()
    {
        Proxy = proxy,
        UseProxy = true
    };
});

2. CNTLM代理配置未启用NTLMv2

Linux上的CNTLM默认可能使用NTLMv1,而目标服务器可能仅支持更安全的NTLMv2。修改cntlm.conf配置文件:

# 启用NTLMv2认证
NTLMv2 yes

修改后重启CNTLM服务:

sudo systemctl restart cntlm

3. Linux缺少NTLM支持依赖库

部分Linux发行版默认未安装NTLM相关依赖,需手动安装:

  • Debian/Ubuntu系:
    sudo apt-get install libntlm0
    
  • RHEL/CentOS系:
    sudo yum install libntlm
    

不使用CNTLM代理的替代方案

方案1:直接使用HttpClient的NTLM认证

若目标服务器支持NTLM认证,可绕过代理直接请求,配置如下:

services.AddHttpClient("WarehousesHttpClient", httpClient =>
{
    httpClient.BaseAddress = new Uri(WarehouseBaseAddress);
    httpClient.Timeout = TimeSpan.FromHours(3);
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
    var handler = new HttpClientHandler();
    // 设置目标服务器的NTLM凭据
    handler.Credentials = new NetworkCredential("WarehousesUsername", "WarehousesPassword", "WarehousesDomain");
    // 允许自动重定向(NTLM认证可能需要)
    handler.AllowAutoRedirect = true;
    return handler;
});

方案2:使用Kerberos认证(若服务器支持)

若目标服务器支持Kerberos,可在Linux上配置Kerberos客户端获取票据后发起请求:

  1. 安装Kerberos客户端:sudo apt-get install krb5-user
  2. 配置/etc/krb5.conf,指定域控制器信息
  3. 获取票据:kinit username@DOMAIN.COM
  4. HttpClient无需额外凭据,系统会自动使用Kerberos票据

方案3:网络层面绕过代理

若部署环境为内部网络,可通过以下方式直接访问目标服务:

  • 配置VPN连接至目标服务所在网络
  • 部署反向代理(如Nginx),将请求转发至目标服务,避免CNTLM代理依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:19:51