我正在使用 dotnet 7 开发一个 Web 服务器,我需要访问使用 NTLM 身份验证的外部 API。
这是我的
program.cs
的片段
private static WebApplicationBuilder CreateWebApplication(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.services.AddHttpClient<IMyService, MyService>()
.ConfigurePrimaryHttpMessageHandler(_ => CreateHandler("myuser", "mypass"));
builder.services.AddControllers();
}
private static HttpClientHandler CreateHandler(string username, string password)
{
return new HttpClientHandler {
PreAuthenticate = true,
UseProxy = false,
UseDefaultCredentials = false,
Credentials = new CredentialsCache
{
{
new Uri("http://myendpoint", "Negotiate", new NetworkCredential(username, password))
}
}
}
}
这是我的服务的片段
public class MyService
{
private HttpClient _client;
public MyService(HttpClient client)
{
_client = client;
}
public async Task Run()
{
HttpRequestMessage req = GenerateHttpReq();
HttpResponseMessage res = await _client.SendAsync(req);
if (!response.IsSuccessStatusCode) {
throw new Exception($"Failed to send request. Status code: {response.StatusCode}");
}
// ... some more processing
}
}
当我运行我的应用程序时,服务中的
Run()
方法被调用,但抛出异常 Failed to send request. Status code: Unauthorized
。
为了确保我在创建 http 客户端时没有做任何错误,我编写了一个可以工作的小应用程序
var handler = new HttpClientHandler {
PreAuthenticate = true,
UseProxy = false,
UseDefaultCredentials = false,
Credentials = new CredentialsCache
{
{
new Uri("http://myendpoint"), "Negotiate", new NetworkCredential(username, password)
}
}
var client = new HttpClient(handler);
var res = await client.PostAsync("http://myendpoint",new StringContent(""));
以上请求已与服务器验证成功。
我应该注意,我正在 Ubuntu 22 机器上运行我的项目。当在我的 Ubuntu 机器上运行这个小测试应用程序时,它失败了,但是当在 Windows 机器上运行它时,它确实工作。我们将项目部署到基于 Linux 的容器,因此我需要它在 Linux 上工作。
发布答案以防万一有人遇到与我相同的问题。
我的问题的解决方案是使用 .NET 8.0 并将以下内容添加到我的
.csproj
文件中
<ItemGroup>
<RuntimeHostConfiguration Include="System.Net.Security.UseManagedNtlm Value="true"/>
</ItemGroup>
我会注意到,我正在官方 dotnet docker 映像上运行我的项目,使用
dotnet/sdk:8.0-jammy
来构建项目,使用 dotnet/aspnet:8.0-jammy
来部署