Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.

If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!

'Inedo.ProGet.Web.Security.UserNotFoundException' on application startup



  • Hi Proget,

    I am trialing out your software and I cannot get the Windows Authentication to work when I start the application up. I have configured the domain access and I can add domain users to the permissions but whenever I turn windows authentication on in IIS it fails to start up with this error (found in the event log):

    Category: Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer
    EventId: 2
    SpanId: f0764a21bc4f2d94
    TraceId: b2ca837a006f687574ebcf26061b736b
    ParentId: 0000000000000000
    RequestId: 40000049-0000-ff00-b63f-84710c7967bb
    RequestPath: /
    Connection ID "18374686480476930118", Request ID "40000049-0000-ff00-b63f-84710c7967bb": An unhandled exception was thrown by the application.
    Exception:
    Inedo.ProGet.Web.Security.UserNotFoundException: Exception of type 'Inedo.ProGet.Web.Security.UserNotFoundException' was thrown.
    at Inedo.ProGet.WebApplication.ProGetHttpModule.AuthorizeRequestAsync(AhHttpApplication app)
    at Inedo.Web.InedoHttpModule.Inedo.Web.IAhWebModule.AuthorizeRequestAsync(AhHttpApplication app)
    at Inedo.Web.AhWebMiddleware.InvokeAsync(HttpContext context)
    at Inedo.Web.AhWebMiddleware.InvokeAsync(HttpContext context)
    at Inedo.Web.AhWebMiddleware.InvokeAsync(HttpContext context)
    at Inedo.Web.AhWebHost.<>c.<b__22_0>d.MoveNext()
    --- End of stack trace from previous location ---
    at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()

    Any suggestions what I have done wrong? I searched your documentation but there was nothing obvious.

    Thanks,

    Darren


  • inedo-engineer

    Hi @Darren-Gipson_6156 ,

    This error means that the username being passed from Windows (e.g. MYDOMAIN\jdoe) cannot be found on the domain.

    This can mean that the netbios alias domain mapping is incorrect (e.g. MYDOMAIN) or that there are some other issues locating the user in the configured directory. Your best bet is to "play around" with searching and settings under the Advanced settings tab of the Directory (under Admin > Security > edit)

    Note you can also try searching for users on that page as well, using the multi-button link in the top-right corner of the page.

    In addition, you can see the information about the user by navigating to /debug/integrated-auth, and that might give some kind of clue where to start.

    Hope that helps point you in the right direction,

    Alana



  • @atripp said in 'Inedo.ProGet.Web.Security.UserNotFoundException' on application startup:

    /debug/integrated-auth

    Thanks @atripp, that URL helped.

    I am seeing something a bit weird though:

    Additional messages:

    • Trying to a Users search for principal "username@domain.com"...
    • Search string is "(&(objectCategory=user)(sAMAccountName=username))"...
    • Searching domain domain.com...
    • Trying to a Users search for principal "domain\username"...
    • Search string is "(&(objectCategory=user)(sAMAccountName=domain\5Cusername))"...
    • Searching domain domain.com...
    • Principal not found.

    It seems to have added extra characters into the search? 5C?

    Test User Directories works though.

    We trialing a Basic licence, not sure if that matters?


  • inedo-engineer

    Hi @Darren-Gipson_6156, sounds like you've found the right tools to configure the integration.

    Here's some more information about the Advanced settings:
    https://docs.inedo.com/docs/various-ldap-v4-advanced

    The DOMAIN\username situation is a little complex. The DOMAIN is considered a NetBios Alias, and needs to be mapped to a domain to search (like domain.com). Then an LDAP query is constructed babsed on that. So in otherwords, you can't search directly for DOMAIN\username in a search like that.

    Try adding a Netbios Alias mapping in the advanced setings, like DOMAIN=domain.com; that might allow you to log-in.



  • Hi @stevedennis

    I think I have worked out what is going on.

    Our domain is called: domain.company.com
    but my user principal name (UPN) is username@company.com

    If I set the Netbios to either domain=domain.company.com or domain=company.com it is does not work I think it because you are using the same string mapping from the Netbios screen to do the domain search.

    It should be noted that not all users have a UPN of @company.com, our groups for example would use: @domain.company.com

    I have tested the filter (&(objectCategory=user)(sAMAccountName=username)) that is provided in the debug output with the get-aduser -ldapfilter PowerShell function and I get back my account, so I know this works.

    For clarity (&(objectCategory=user)(sAMAccountName=domain\username)) does not work in PowerShell.

    I also am able to lookup groups and logins in the search when setting permissions in the interface. I am able to test the login using this button below.

    55fa9b3c-845c-47eb-8541-0a2413f206d6-image.png

    I should add that the server, lookup account and my account are all on the same domain.


  • inedo-engineer

    Hi @Darren-Gipson_6156 ,

    The Netbios mapping is used to convert a username from DOMAIN\username to username@domain.com . You can see how it works in the code here:
    https://github.com/Inedo/inedox-inedocore/blob/master/InedoCore/InedoExtension/UserDirectories/ADUserDirectoryV4.cs#L228

    I'm not sure if that helps. But before getting integrated authentication working, I would make sure you can login username@company.com and your domain password. Once you can do that, then adding WIA will basically just bypass the password check, but you may need to convert that DOMAIN to company.com

    Alana



  • @atripp Thanks for providing a link to the code, I have managed to download it and create some unit tests against the class in question.

    I can not reproduce the issue locally, however, so I need to see if I can understand what is being used by the program at the point of search.

    I would like to add this line:

    this.LogDebug($"Searching domain using BaseDn: {baseDn}, search string: {searchString.ToString()}, scope: {scope} and username of: {this.Username?.GetDomainQualifiedName(this.Domain)}...");

    to before this line

    so that I can understand what the program is using in it's search params.

    I have also tried configuring Stdout to a file but this does not provide enough information other than what I found in the event log.

    It should be noted that the Test User Directories tool is successful with my current configuration:

    a625c0bf-a5dc-4538-b4cd-ebc028695fb7-image.png

    I have also upgraded to the latest version of ProGet.


  • inedo-engineer

    Hi @Darren-Gipson_6156 ,

    That's great you were able to find the code to change, at least to help find more information. Since you've got that far, I would recommend just bundling it as a zip file and adding the extension to ProGet to try it out:
    https://docs.inedo.com/docs/proget-administration-extensions

    Let us know if you run into any issues with that; that will probably amke it easiest to iterate, so you don't have to wait for us to build pre-release extensions .

    Thanks,
    Alana



  • Thanks for the suggestion @atripp, I can see now how to update the version that I am using so that I can debug the issue, however every time I run the command to create the upack file:

    dotnet inedoxpack pack . --build Release
    

    I get:

    Executing dotnet publish for InedoExtension.csproj (net8.0)...
    No extensions were found in [redacted]\AppData\Local\Temp\inedoxpack\9071c72b2a204ce4b73abe172916f842
    

    any idea what I have done wrong here?

    I am following the guide here


  • inedo-engineer

    Hi @Darren-Gipson_6156,

    It looks like we hadn't published the latest version of inedoxpack to nuget.org. I've now published it manually, so if you run dotnet tool update inedo.extensionpackager, it should update to v1.0.7, which will be able to build the extension.

    Sorry about that!



  • Thanks @gdivis, I have managed to update the extension as required. I have reviewed the code and it would appear to be finding my username successfully when called from this stack trace:

    - Called by: ADUserDirectoryV4.TryGetPrincipal
    - Called by: ADUserDirectoryV4.TryGetUser
    - Called by: <ProcessRequestInternalAsync>d__0.MoveNext
    - Called by: AsyncMethodBuilderCore.Start
    - Called by: AsyncTaskMethodBuilder.Start
    - Called by: IntegratedAuthHandler.ProcessRequestInternalAsync
    

    However when it is called from here:

     - Called by: ADUserDirectoryV4.TryGetPrincipal
     - Called by: ADUserDirectoryV4.TryGetUser
     - Called by: UserDirectory.TryGetUserAsync
     - Called by: <ProcessRequestInternalAsync>d__0.MoveNext
     - Called by: AsyncMethodBuilderCore.Start
     - Called by: AsyncTaskMethodBuilder.Start
    

    It fails, because it passes through domain\5cusername to the LDAP search, even without the 5C in the search parameters, this would have never worked, as the LDAP query returns no results when I test it in PowerShell.

    How do I disable the second search?


  • inedo-engineer

    Hi @Darren-Gipson_6156,

    Thanks for all that information. I'm sorry this is taking so long to figure out, but LDAP/AD and Integrated Windows Authentication are always difficult to track down.

    Just a few notes on the query process.

    • The NETBIOS mappings in the UI just help to speed up the LDAP query process because it removes the need to query for the NETBIOS mapping from the domain controller. If you leave that blank, it will search for the netbios mapping in the domain directly Line 418. With that said, it will then cache that result so it doesn't have to query each time.
    • The \5c you are seeing is the LDAP library we use (System.DirectoryServices on Windows and Novell.Directory.Ldap.NETSTandard on Linux) encoding the username in the LDAP query. It shouldn't be searching for domain\user in that query, so most likely there is a bug in part of that process.

    Can you tell me what ProGet installation you are using (InedoHub or Docker) and which web server you are using (IIS or Integrated)?

    One last thing, can you test a few things for me? This will help my pinpoint the issue further.

    1. With Integrated Windows Authentication disabled, can you verify you can login with the following usernames using the Login Page:
      1. Use username@domain.com
      2. Use DOMAIN\username
    2. With Integrated Windows Authentication enabled, can you navigate to http://yourprogetserver/debug/integrated-auth and send the results? If you need to distort the usernames, can you please leave format visible?

    If you do not feel comfortable posting the results of the debug page, you can email them to support@inedo.com with the subject [QA-1565] Results.

    Thanks,
    Rich



  • Thanks for getting back to me Rich. I have run a number unit tests against the TryGetUser method and I struggle to make it break unless I provide it with invalid parameters. I think the issue is the UserDirectory.TryGetUserAsync method which appears to be running outside of the InedoCore library.

    We are using InedoHub, with IIS.

    With Integrated Windows Authentication disabled, can you verify you can login with the following usernames using the Login Page:

    1. Using username - works
    2. Using username@domain.com - works
    3. Using DOMAIN\username - works

    I have emailed this to you.

    Please let me know if you any further information.

    Thanks,

    Darren


  • inedo-engineer

    Hi @Darren-Gipson_6156,

    Thank you for getting back to me. I got your email and this is all very helpful! I think I see where the issue is occurring. As you noted, it looks to have to do with how we are converting the integrated authentication user to a user principal in the HTTP context. I'm going to need to dig into this a little bit, but I should have an update by mid-day tomorrow (I'm in the EST timezone). I'll let you know what I find.

    While I'm diving into this. Can you try restarting IIS after you enable integrated authentication and try again? I just want to rule out security caching.

    Thanks,
    Rich



  • Hi Rich,

    Yes, I have tried several times to recycle and reboot the server, it still gives me the same issue.

    Thanks for looking into this.


  • inedo-engineer

    Hi @Darren-Gipson_6156 ,

    I think I have finally recreated the issue. Can you please try something for me? Please configure integrated authentication following these steps:

    1. On the ProGet site in IIS, enable Anonymous authentication
    2. In ProGet, login as an administrator and navigate to Administration -> Manage Security and enable windows integrated authentication (do not worry about the warning about not seeing a login user).
    3. On the ProGet site in IIS, disable Anonymous Authentication and enable Windows Authentication

    Once you do that, does windows authentication work?

    It looks like there was a change in .NET 8.0 that automatically sets the User Principal on the HTTP Context to windows authentication name. By following the steps above, I was able to configure Windows Authentication in IIS to work around this issue.

    Thanks,
    Rich



  • many swear words. I must have been so close to that solution by accident. 😢

    Yep that's working now 😄 thanks very much Rich.


  • inedo-engineer

    Hi @Darren-Gipson_6156,

    No problem! Glad it is working. ProGet 2024.6 will include a fix for this issue, PG-2695. So hopefully this won't happen again!

    Thanks,
    Rich


Log in to reply
 

Inedo Website HomeSupport HomeCode of ConductForums GuideDocumentation