使用 HttpClient 在 mac 上的 dotnet 核心应用程序中使用 Network Creds

Using Network Creds in dotnet core app on a mac using HttpClient

正在编写一个 dotnet 核心应用程序。我需要使用网络凭据登录,因为服务(恰好是 TFS 本地服务器)使用这些凭据进行身份验证。来自我(和其他团队成员)windows machine,以下代码有效:

Console.WriteLine("Type in your DOMAIN password:");
var pass = GetPassword(); //command line secure string magic from SO
var networkCredential = new NetworkCredential("USERNAME", pass, "DOMAINNAME");
string tfsDefaultCollection = "https://TFSURL/DefaultCollection";

string testUrl = $"{tfsDefaultCollection}/_apis/tfvc/changesets/1234/changes?api-version=2.2";

var httpClientHandler = new HttpClientHandler
{
    Credentials = networkCredential
};

var client = new HttpClient(httpClientHandler)
{
    BaseAddress = new Uri(testUrl)
};
httpClientHandler.PreAuthenticate = true;

var test = client.GetAsync(testUrl).Result;

Console.WriteLine(test);

但它在我的 mac 上不起作用。我得到一个未经授权的 401。两者都使用相同的硬连线连接。这适用于我的 mac:

curl --ntlm --user "DOMAINNAME\USERNAME" "https://TFSURL/DefaultCollection/_apis/tfvc/changesets/1234/changes?api-version=2.2"

所以我认为这排除了连接问题。我是否遗漏了我需要在 mac 上做的事情?谁能指出一些文档或方法来解决这两个请求在最低级别上所做的事情,看看是否存在差异?

好吧,终于有一些 google-foo 把我带到了那里。 linux/mac 的 dotnet 核心中存在错误。此问题描述了修复:

https://github.com/dotnet/corefx/issues/25988#issuecomment-412534360

这与您要连接的主机同时使用 Kerberos 和 NTLM 身份验证方法有关。

执行如下:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

Console.WriteLine("Type in your DOMAIN password:");
var pass = GetPassword(); //command line secure string magic from SO
var networkCredential = new NetworkCredential("USERNAME", pass, "DOMAINNAME");
string tfsDefaultCollection = "https://TFSURL/DefaultCollection";

string testUrl = $"{tfsDefaultCollection}/_apis/tfvc/changesets/1234/changes?api-version=2.2";

var myCache = new CredentialCache
{
    {
        new Uri(testUrl), "NTLM",
        networkCredential
    }
};

var httpClientHandler = new HttpClientHandler
{
    Credentials = myCache
};

var client = new HttpClient(httpClientHandler)
{
    BaseAddress = new Uri(testUrl)
};
httpClientHandler.PreAuthenticate = true;

var test = client.GetAsync(testUrl).Result;

Console.WriteLine(test);

感谢@dmcgill50 让我走上了正确的谷歌搜索轨道。