Issue in Implementing Windows Authentication and LDAP in .NET 6

Srivastava, Prashant 1 Reputation point
2022-05-30T19:04:57.923+00:00

Hi Team,

We have a intranet web api hosted in Windows box (on prem) which is consumed by our Angular UI and we need to implement Integration Windows Authentication in the API side. I was looking into the MS docs (see below url) and noticed that there is "AddNegotiate" method which can help us authentication / authorize user.

There are couple of things which we need to do as part of authentication:-

  1. On Launch of API if user is already not Authenticated then have him logged In.
  2. For Login there is no Login screen so we have to go for Integrated Windows Authentication (IWA). -- Here, browser should not prompt to enter credentials. I.e. should be passwordless.
  3. As part of this IWA we have to authenticate the user and use LDAP to pull the user groups.
  4. Set User groups to Claims Principal.
  5. Create a token so that for subsequent calls token can be used for authentication. Rather, than hitting the LDAP again and again (basically, checking the Policy)
  6. Have those token stored in File System so that we can have a concept of shared authentication. Because, we have multiple web nodes for our application.
  7. This way If there are 10 api calls on a page. And, 1st api call goes to web node 1 and rest of the api calls goes to web node 2 (based on Load balancer) then web node 2 should use the token already given by web node 1. They should not try to authenticate the user as he / she was already authenticated on Node 1.

Current Problem Statement:-

  1. When we are running our API from VS IDE using IISExpress with "iisSettings -> windowsAuthentication" in "launchsettings.json" file to true. Then browser is prompting to enter credentials.
  2. Also, I see there is a method by the name "EnableLDAP". But, when to try to pass LDAP GlobalCatalog then it throws error to us. However, If write simple LDAP code logic using "DirectoryEntry" with GlobalCatalog then it works.

Question:-

  1. Can you please help us understand what can we do here to authenticate user without having them enter credentials on browser and user LDAP GlobalCatalog to get their user groups and add them to ClaimPrincipal.

Reference URL:-
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-6.0&tabs=visual-studio

Regards,
Prashant Srivastava

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,148 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Srivastava, Prashant 1 Reputation point
    2022-06-01T17:18:04.053+00:00

    As far as I know, we can't authenticate the user without entering the credentials on the browser.

    @Zhi Lv - MSFT
    We can do it by enabling both Windows and Anonymous authentication together.
    Currently the way I have the code in my system is - basically a hybrid approach (as mentioned above), and then further following the MS docs approach mentioned in reference url I shared earlier.

    services.AddTransient<IClaimsTransformation, LdapUserClaimsTransformer>();  
    services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate()  
    

    Problem with above approach is :
    Since I have am hitting the LDAP inside "LdapUserClaimsTransformer" class and building the user claims there. And, this is called in each and every request. So, due to this it is called multiple times. And, in turn hitting the LDAP for every time and alternatively recreating the claims too. [WHICH DO NOT WANT TO DO]

    I see there is approach for NegotiateHandler. However, I do not see a good sample of using it. Assuming this won't hit for every request If you can help me understand how can I implement a custom NegotiateHandler then I can may be fix this issue and remove the ClaimsTransformation thing.

    About this question, might be you need to override the build in handling method to get the groups, but I didn't find it from the official document. So, I suggest you could feedback this issue by clicking the "This Product" button at the bottom

    Thanks! Will do. Just one quick question. Do you by chance know - how soon we get response post submitting a feedback.

    Regards,
    Prashant Srivastava

    0 comments No comments

  2. Bruce (SqlWork.com) 55,196 Reputation points
    2022-06-01T18:30:15.123+00:00

    when you use IWA, authentication is done by IIS and the browser (as the browser does not pass the domain name, IIS is configured with a default). the asp host module will create a WindowsPrincipal from the usertoken passed by IIS. the core module will then pass the WindowsPrincipal to asp.net core. the AspNetCore core authentication middleware will use the passed WindowsPrincipal for authentication. This is done on every request. The WindowsPrincipal is the supplier of roles/claims see:

    https://learn.microsoft.com/en-us/dotnet/api/system.security.principal.windowsprincipal?view=net-6.0

    in the case of hosting on linux/macOS, asp.net core needs to do the windows authentication itself. as directory services and WindowsPrincipal is not supported on linux/macOS, to valid the username/password ldap is used. you may also load roles via ldap, but this may not be quick and is optional, thus its a separate configuration option. adding EnableLdap has no effect is hosted by IIS.