Forum Discussion

iandeherdt's avatar
iandeherdt
Copper Contributor
Feb 13, 2023

HttpClient on .NET 7 fails on Kerberos authentication

We've upgraded our application from .NET 6 to .NET 7 and now the Kerberos authentication fails. I've created a simple console application to replicate the behavior and built it for both .NET 6 and .NET 7. The .NET 6 application does a successful authentication, but .NET 7 fails with the stacktrace below.

- OS: Windows Server 2019 Standard
- .NET Version: 7
- Application: WPF and
Console App, same behavior.

 

using System.Configuration;

Console.WriteLine("Beep boop bop... starting application");
HttpClientHandler handler = new()
{
UseDefaultCredentials = true,
PreAuthenticate = true,
};
handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => {
return true;
};

HttpClient client = new(handler);

string url = ConfigurationManager.AppSettings["IdpUrl"];
Console.WriteLine($"Requesting: {url}");

HttpResponseMessage? response = await client.GetAsync(url);

Console.WriteLine($"Response status code: {response.StatusCode}");
Console.WriteLine($"Response: {response}");

Console.WriteLine("Beep boop bop... signing off");

Console.ReadLine();

 

The stacktrace:


System.Net.Http.HttpRequestException: Authentication validation failed with error - InvalidToken. at System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, Boolean async, ICredentials credentials, Boolean isProxyAuth, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, Boolean async, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)


From a Kerberos point of view, this is the normal process:

- Call happens to a URL
- The server replies with met een 401 and WWW-Authenticate: Negotiate header
- Client replies with a kerberos token
- The server does the Kerberos validation and returns a 200 reply with in the body a valid JWT which is the case.

I've omitted the token(s) for privacy reasons and added some X's where other data use to be.
Fiddler results for the Kerberos authentication:

```
HTTP/1.1 401
Server: xxxxxxxx
Date: Mon, 06 Feb 2023 10:13:22 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 519
Connection: keep-alive
Set-Cookie: XX_JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXXXXX; Path=/xx; Secure; HttpOnly; SameSite=None
Cache-Control: no-store
WWW-Authenticate: Negotiate
Pragma: no-cache
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubdomains;
Cache-Control: private, max-age=0, no-cache, no-store
Pragma: no-cache
Proxy-Support: Session-Based-Authentication
```

```
HTTP/1.1 200
Server: xxxxxx
Date: Mon, 06 Feb 2023 10:13:22 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 1124
Connection: keep-alive
Set-Cookie: XX_JSESSIONID=XXXXXXXXXXXXXXXXXX; Path=/xx; Secure; HttpOnly; SameSite=None
WWW-Authenticate: Negotiate (A TOKEN)
Cache-Control: max-age=0
Pragma: no-cache
Expires: Mon, 06 Feb 2023 10:13:22 GMT
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubdomains;
Cache-Control: private, max-age=0, no-cache, no-store
Pragma: no-cache
```

1 Reply

  • LanHuang's avatar
    LanHuang
    Iron Contributor

    Hi  iandeherdt,

    Thanks for posting your issue here.

    However this platform is used for how-to discussions and sharing best practices for building any app with .NET.Since your issue is a technical question, welcome to post it in Microsoft Q&A forum, the support team and communities on Microsoft Q&A will help you for any technical questions.
    Besides, it will be appreciated if you can share it here once you post this technical question Microsoft Q&A.
    Best Regards,
    Lan Huang

     

Resources