You might be using the following method to attempt Integrated Windows Auth while using Microsoft Authentication Library (MSAL)…

result = await app.AcquireTokenByIntegratedWindowsAuth(scopes)

and you are getting one of the following errors…

  • Microsoft.Identity.Client.MsalClientException: Failed to get user name —> System.ComponentModel.Win32Exception: No mapping between account names and security IDs was done
  • Microsoft.Identity.Client.MsalClientException: Failed to get user name —> System.ComponentModel.Win32Exception: Access Denied

Make sure you at least meet these minimum requirements:

  • You are running the app as a local Active Directory user and not a local computer user account.
  • Ensure that the device is joined to the domain

What is actually failing?

MSAL makes a call to GetUserNameEx function from secur32.dll…

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/blob/01ecd12464007fc1988b6a127aa0b1b980bca1ed/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/WindowsNativeMethods.cs#L66

For more information about GetUserNameEx…

https://learn.microsoft.com/en-us/windows/win32/api/secext/nf-secext-getusernameexa

Windows is returning this error message. There is a number of reasons this can fail that is out of scope for this article.

Manually pass the username to AcquireTokenByIntegratedWindowsAuth

If you already know ahead of time what the username is, you can just pass it manually to MSAL… This may be by far the easiest and recommended solution.

result = await app.AcquireTokenByIntegratedWindowsAuth(scopes).WithUsername(“serviceaccount@contoso.com”)

You can try other ways to dynamically get the username….

Use System.Security.Principal.WindowsIdentity.GetCurrent()

Note: If returns a username with no domain, this will not work and return different errors. For proper Azure Active Directory integration, we need to pass username in the format of user principal name.

string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
result = await app.AcquireTokenByIntegratedWindowsAuth(scopes).WithUsername(username)

Use PublicClientApplication.OperatingSystemAccount.Username

Note: This attempts to access the Windows Account Broker to get the user signed into the device. This is not going to work if running on IIS or Windows Servers

string username = PublicClientApplication.OperatingSystemAccount.Username;
result = await app.AcquireTokenByIntegratedWindowsAuth(scopes).WithUsername(username)

For more information

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Integrated-Windows-Authentication

Leave a Comment