Skip to content

SocketsHttpHandler cannot authenticate NTLM with username format user@domain.com #94303

Closed as not planned

Description

@rolfbjarne

From @vinhdp195 on Fri, 27 Oct 2023 04:50:42 GMT

For Xamarin.iOS https://github.com/dotnet/designs/blob/main/accepted/2020/mono-convergence/platform-specific-httpclient.md#xamariniostvoswatchos
There are 3 handlers available (SocketsHttpHandler, CFNetworkHandler, and NSUrlSessionHandler)
After upgrading to NET7, it’s similar.

However, NTLM authentication is not working well.
SocketsHttpHandler cannot authenticate with a username in the form of user@domain.com.
There is a difference between NSUrlSessionHandler and SocketsHttpHandler.
I need to know why this difference exists.

Environment
Currently running on IOS devices with version 15/16 (Iphone/Ipad)
Visual Stuido 2022 version 17.5.4
Xcode_14.2
xamarin.ios-16.0.0.72
MonoFramework-MDK-6.12.0.182.macos10.xamarin.universal

Project sample:
https://github.com/vinhdp195/HttpRequestSample

Code sample:
https://github.com/vinhdp195/HttpRequestSample/blob/main/MauiApp1/MainPage.xaml.cs

In the above example source:
CheckHttpAsync() method uses NSUrlSessionHandler as a parameter for HttpClient
CheckSocketAsync() method uses SocketsHttpHandler as a parameter for HttpClient

User Infomation in AD:
user logon name: admin@sample.com
user logon (pre-windows 2000) : domain\samName
samAccountName is "samName"
2023-10-27_110843

Results when authenticating NTLM with SocketsHttpHandler and NSUrlSessionHandler:

No. Username Input NSUrlSessionHandler SocketsHttpHandler
1 samName 〇 〇
2 domain\samName 〇 〇
3 admin@sample.com 〇 x
4 samName@sample.com x 〇
5 samName@domain.com x 〇
6 samName@xyz.com x 〇

It appears that only username is samName can be authenticated (OK) when using SocketsHttpHandler.

  • At No.3: using SocketsHttpHandler, it cannot authenticate with the username “admin@sample.com”, but NSUrlSessionHandler can.
  • At No.4,5,6: using SocketsHttpHandler, it can authenticate with samName, however, any value after the @ character can also successfully authenticate (xyz is an incorrect value but still authenticates successfully).

What is the reason for the above difference? Is it a bug?
I want to be able to successfully authenticate at No.3 using SocketsHttpHandler, what should I do?
(Besides, the reason I have to use SocketsHttpHandler for my project is because NSUrlSessionHandler on iOS does not support passing in WebProxy)

Copied from original issue dotnet/macios#19366

Activity

  1. rolfbjarne commented on Nov 2, 2023

    @rolfbjarne
    MemberAuthor

    From @vinhdp195 on Wed, 01 Nov 2023 08:04:32 GMT

    I want to be able to successfully authenticate at No.3 using SocketsHttpHandler, what should I do?

  2. rolfbjarne commented on Nov 2, 2023

    @rolfbjarne
    MemberAuthor

    From @rolfbjarne on Thu, 02 Nov 2023 16:31:30 GMT

    Moving to dotnet/runtime since that's where the code for SocketsHttpHandler lives, and it seems that's what this issue is about.

  3. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Nov 2, 2023
  4. rolfbjarne commented on Nov 2, 2023

    @rolfbjarne
    MemberAuthor
  5. steveisok commented on Nov 2, 2023

    @steveisok
    Member
  6. wfurt commented on Nov 2, 2023

    @wfurt
    Member

    cc: @filipnavara AFAIK the admin@sample.com should work. I don't understand the difference between 3 & 4.

  7. filipnavara commented on Nov 2, 2023

    @filipnavara
    Member

    Apple's GSSAPI implementation of NTLM always rewrites admin@sample.com into sample.com\admin, ie. always extracts the domain. This behavior is incorrect but happens to work in many cases. NSUrlSession has its own NTLM implementation that doesn't do this credential rewriting. This is one of the reasons why we exposed UseManagedNtlm in .NET 8 (and made it default for .NET 9 on macOS).

  8. filipnavara commented on Nov 2, 2023

    @filipnavara
    Member

    I'll try to post an example on how to use UseManagedNtlm later if no one else beats me to it. The gist is that the GSSAPI doesn't work correctly for samName != admin. The names are usually the same but longer ones get truncated, etc. Similarly, this breaks some domain fallback paths when the application server is not on the same domain as the authentication server.

  9. filipnavara commented on Nov 2, 2023

    @filipnavara
    Member

    @vinhdp195 It would be useful if you can test with the UseManagedNtlm option on .NET 8. To enable it, you can add this to the .csproj file:

    <ItemGroup>
        <RuntimeHostConfigurationOption Include="System.Net.Security.UseManagedNtlm" Value="true" />
    </ItemGroup>

    This should replace the NTLM implementation for SocketsHttpHandler with a managed one written in .NET. This the same implementation that shipped on Android in .NET 7.

  10. vinhdp195 commented on Nov 7, 2023

    @vinhdp195

    @filipnavara

    It would be useful if you can test with the UseManagedNtlm option on .NET 8. To enable it, you can add this to the .csproj file:

    I tried as you suggested.
    The environment is as follows:
    .NET 8.0 (8.0.100-preview.3)
    Visual studio Enterprise 2022 Version 17.7.6
    Device : Ipad ios 16.1

    Source code:
    https://github.com/vinhdp195/HttpRequestSample/tree/Net8
    https://github.com/vinhdp195/HttpRequestSample/blob/Net8/MauiApp3/MauiApp3.csproj
    Line 49:

    Results:
    In case No.3, SocketsHttpHandler still cannot authenticate. It returns Error Code 401.

    In your environment, with the source code as above, is it possible to authenticate successfully (Code 200 OK) or not?

  11. CarnaViire commented on Nov 9, 2023

    @CarnaViire
    Member

    Triage: we should investigate in 9.0

  12. added this to the 9.0.0 milestone on Nov 9, 2023
  13. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on Nov 9, 2023
  14. vinhdp195 commented on Nov 13, 2023

    @vinhdp195

    @filipnavara @CarnaViire
    Thank you for your answer.
    Regarding the comment above, can I confirm that the latest Net 8 version rc.2 still cannot fix the bug?
    Do I need to wait for the Net9 release to be able to check?

  15. filipnavara commented on Nov 13, 2023

    @filipnavara
    Member

    In your environment, with the source code as above, is it possible to authenticate successfully (Code 200 OK) or not?

    I didn't get to test it yet, and I don't have the server environment readily available at the moment. I hope to test it soon, perhaps later this week.

  16. vinhdp195 commented on Nov 15, 2023

    @vinhdp195

    @filipnavara @CarnaViire
    I have successfully tested with net8-rc2.
    I was able to authenticate with UPN of patern No.3.

    Environment as below:
    Source code: https://github.com/vinhdp195/HttpRequestSample/tree/Net8-RC2
    .NET version: 8.0.0-rc.2.23479.6
    Device : Ipad Gen 6 (IOS 17.1)
    Visual Studio version: 17.8.0 Preview 6
    Xcode version : 15

  17. CarnaViire commented on Nov 15, 2023

    @CarnaViire
    Member

    @vinhdp195 do I understand correctly that .NET 8 works properly in all cases, and this issue can be closed?

  18. akoeplinger commented on Nov 15, 2023

    @akoeplinger
    Member

    Note that you can also set the <_UseManagedNtlm>true</_UseManagedNtlm> property in the csproj, it will set the same RuntimeHostConfigurationOption: https://github.com/dotnet/sdk/blob/992d660097927ddd4964b52219ea89d4175f66a1/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets#L558-L561

    @filipnavara do you remember why this was added as a "private" msbuild property with underscore?

  19. filipnavara commented on Nov 15, 2023

    @filipnavara
    Member

    @akoeplinger That property was only added in .NET 9 and it was not backported to .NET 8 SDK. Underscore is generally used for unsupported/undocumented properties. In .NET 9 the default value for iOS/macOS was changed anyway, so the property would not help in this case.

  20. vinhdp195 commented on Nov 17, 2023

    @vinhdp195

    @CarnaViire

    do I understand correctly that .NET 8 works properly in all cases, and this issue can be closed?

    That's right. At Net8, after applying UseManagedNtlm, I was able to resolve the error this time.

  21. CarnaViire commented on Nov 17, 2023

    @CarnaViire
    Member

    Thanks. Closing as answered.

  22. filipnavara commented on Nov 17, 2023

    @filipnavara
    Member

    @CarnaViire I'd like to ask again about backporting dotnet/sdk#34903 to .NET 8 SDK. It was done late in the .NET 8 cycle and the backport question somehow drowned in the noise. It adds the <_UseManagedNtlm>true</_UseManagedNtlm> property on SDK level instead of relying on <RuntimeHostConfigurationOption Include="System.Net.Security.UseManagedNtlm" Value="true" /> which is hard to discover and error-prone.

  23. CarnaViire commented on Nov 17, 2023

    @CarnaViire
    Member

    I'm not sure it will meet the bar for a backport at this point... given that the app-context switch exists and works... cc @wfurt @dotnet/ncl @vitek-karas @sbomer

  24. locked and limited conversation to collaborators on Dec 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions