runtime: Basic Authentication via HTTPClientHandler not working for Android
Description
The basic authentication via HTTPClientHandler credentials doesn’t work for Android (.net 7.0). Can you confirm, this is a bug or is something wrong with the coding below? Thanks, Michael
Steps to Reproduce
- Create MAU project .net 7.0
- add the following coding:
HttpClientHandler lClientHandler = new HttpClientHandler();
CancellationTokenSource lCancel = new CancellationTokenSource();
lCancel.CancelAfter(TimeSpan.FromMilliseconds(5000));
lClientHandler.Credentials = new NetworkCredential("<user>", "<password>");
var lClient = new HttpClient(lClientHandler);
var lResponse = await lClient.GetAsync("https://<web address>" , HttpCompletionOption.ResponseContentRead, lCancel.Token).ConfigureAwait(false);
This returns a 401 (Unauthorized) for android. The same code works just fine for windows. I have tested the problem with multiple android emulators (Android 11 and Android 13) and an android device (Android 13). The web service is accessible via browser on the device (and the login/password works as well).
Link to public reproduction project repository
Version with bug
7.0 (current)
Last version that worked well
Unknown/Other
Affected platforms
Android
Affected platform versions
Android 11/ Android 13, probably others as well
Did you find any workaround?
If I set the Authorization manually it works just fine.
(Instead of:
lClientHandler.Credentials = new NetworkCredential("<user>", "<password>");
for instance use:
var byteArray = Encoding.ASCII.GetBytes("<user>:<password>");
lClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
) However this workaround doesn’t really work for me, because the code is part of a library implementation I use and which I cannot change. Furthermore this coding works in a Xamarin Android app (non MAUI) without problem.
Relevant log output
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 21 (18 by maintainers)
Should it? This makes it problematic for anybody who wants to write portable code that runs same on all platforms. It would be great IMHO if people do not need to understand all the platform differences.
@simonrozsival yeah, it’s a bit of a confusing mess… Perhaps handling 401 would make sense, even at the cost of the extra request. It would be enabled by default, with a way to disable it (a property on
AndroidMessageHandler
) if need be. I suppose most people would be fine with this kind of a breaking change.AFAIK the default native handler that’s used internally by HttpClientHandler on Android won’t include Credentials by default. I would recommend using the AndroidMessageHandler directly and configuring its
PreAuthenticate
andPreAuthenticationData
properties. What’s also necessary is that the server sends theWWW-Authenticate: Basic
header.Here’s a short sample:
The expected output is: