-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Android] Provide the option to use NTLM Authentication #62264
Comments
Tagging subscribers to 'arch-android': @steveisok, @akoeplinger Issue DetailsUnlike our other configurations, there is no library we rely on and can safely ship that provides NTLM authentication. As a result, we will need to incorporate a managed implementation largely based off of @wfurt's work in https://github.com/wfurt/Ntlm. Work Items
|
JFYI I have an open PR on @wfurt's Ntlm repository that implements couple of the missing features and security mechanisms. It should be reviewed/updated/merged before you proceed with integrating the code. |
AFAIK @dotMorten has working implementation on Android. Is that something you can share/contribute @dotMorten? |
I can definitely share it. Need to dig it out. Not sure I’d call that contribute as I just put together a few things from other contributors and got help to get it working |
Here you go: https://github.com/dotMorten/NtlmAndroid Most of how this differs is it has 0-dependencies. I lifted the MD4 and Asn1 implementations from this repo, and just modified @wfurt's code to work with these classes instead. So most of the code in the repo can be deleted since it is already available (as internal) in the .net runtime sdk. |
Thanks for your feedback @wfurt and @dotMorten ! To make progress, I can pull the solution, put it into a separate branch against runtime repo and start cleaning it up. |
@dotMorten Uff, that is based on the code before I sent out PR wfurt/Ntlm#2. It's missing couple of important security features and most importantly, some of these are required with newer Windows setups. It also looks quite close to https://github.com/JeroenBer/Ntlm where I found couple of bugs too and sent a PR (also not merged). I'd be happy to review any PR but at the moment I cannot commit to coding this myself. I'd strongly urge to fix the security and compatibility issues/features first before proceeding with the integration. Some of the changes fundamentally require to keep the state throughout the authentication on the client side (to calculate checksum) and it may influence how the code is integrated. |
@filipnavara Glad to have you as a reviewer, thanks! If we need to follow any formal procedure to preserve authoring, then perhaps, it'd make sense that @dotMorten opened a draft PR with the "as-is" solution against dotnet/runtime and I could join this work and address any issues on that. |
No need to have me be author, considering I really wasn't for 99% of the code, but it is mainly wfurt's code, and he's already assigned here. |
I'll try to stabilize the core NTLM with @filipnavara (probably next week) and then I'll bring it to runtime. That should allow to unblock work on the android specific part e.g. integration with platform handler. |
I have started experimenting with an integration here: https://github.com/filipnavara/runtime/tree/managed_ntlm. It's very much work in progress and I expect to do a lot of cleanup and testing tomorrow. It basically just wires the code into System.Net.Http and gets the basic scenario working. Aside from correctness of the code itself (eg. validation, buffer usage, etc.) Update: I added basic implementation of the |
The branch linked in the comment above should compile and it works against my test servers. I've marked couple of the spots that need to be fixed in the source code comments. There's definitely more things than that though (big endian compatibility, unnecessary usage of How do we move forward from here? I can open a PR to allow you to commit to the branch and to make it easier to discuss issues with the code. (Note that there's a temporary test case that connects to my hosted server, including plain text credentials. The server is a burner so it's not a problem for the moment. It also crashes about once per day. [Thanks, Azure!] We just need to remember to remove it before merging.) |
@filipnavara Thanks! AFAIU we need to integrate it with XA's
Perhaps, you might want to add a couple more thoughts on that? |
It took me a bit of a time to give it a thought and see what is actually the problem scope and if there's an easy way to approach it. Let's start with several observations:
That leads to a question what is the minimal viable implementation. Implementing the NTLM/SPNEGO on If we wanted
Each of these options have significant downsides and/or costs. Maintaining a copy of the code seems like a non-starter to me. We'd want ¹) I'll open separate issue to track this. The gist is that the same credentials work on Windows but don't work on macOS. A different variation of the credentials works on both. The scenario involves a typical Exchange setup with server E and AD, E being the Exchange server and AD being the Active Directory server. User tries to authenticate with user name "u@b.c" to E. "b.c" is email domain that exist on the Exchange server but it's neither an AD domain nor a DNS domain name setup on the AD. On Windows the credentials are sent as user |
Thanks @filipnavara for great detailed summary. I agree that session-based auth and challenge-response are important concepts to consider. |
The Kerberos.NET implementation is quite amazing but at the moment I am looking into breaking this up into more managable chunks. Btw, the reflection over I don't like the reflection based approach and it reinforces my belief that public API is in order. However, worst case, it is possible to reuse that on the xamarin-android side. |
I agree. That was more note about what we could do in the future. And while #29270 was focused on server IMHO, we can push that forward if that makes it easier for us. |
I believe there is a 4th option. Move AndroidMessageHandler into runtime and give it some JNI treatment. The difficult part would be if we need to subclass any of the java API's to pull NTLM off. In runtime, we've resisted having to do such a thing in the past, but maybe this is enough to reopen that discussion. |
#29270 is merged and there is now API sufficient for the handler. |
Thanks to #66879 the |
Context: dotnet/runtime#62264 Context? https://github.com/wfurt/Ntlm Update `Xamarin.Android.Net.AndroidMessageHandler` to *optionally* support NTLMv2 authentication in .NET 7+. This authentication method is recommended only for legacy services that do not provide any more secure options. If an endpoint requires NTLMv2 authentication and NTMLv2 is not enabled, then the endpoint will return HTTP-401 errors. NTLMv2 authentication can be enabled by setting the `$(AndroidUseNegotiateAuthentication)` MSBuild property to True. If this property is False or isn't set, then NTLMv2 support is linked away during the package build. Example `.csproj` changes to enable NTLMv2 support: <PropertyGroup> <AndroidUseNegotiateAuthentication>true</AndroidUseNegotiateAuthentication> </PropertyGroup> Example C# `HttpClient` usage using NTLMv2 authentication: var cache = new CredentialCache (); cache.Add (serverUri, "Negotiate", new NetworkCredential(username, password, domain)); var handler = new AndroidMessageHandler { Credentials = cache, }; var client = new HttpClient (handler); var response = await client.GetAsync (requestUri); // 200 OK; 401 is NTLMv2 isn't enabled
Fixed by dotnet/android#6999 |
Thank you everyone! I have quite a few customers who's going to be happy about this. |
Unlike our other configurations, there is no library we rely on and can safely ship that provides NTLM authentication. As a result, we will need to incorporate a managed implementation largely based off of @wfurt's work in https://github.com/wfurt/Ntlm.
Work Items
The text was updated successfully, but these errors were encountered: