Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs
Contact   •   Articles   •   Products   •   Support   •   Search
Ad-free experience sponsored by:
ASPOSE - the market leader of .NET and Java APIs for file formats – natively work with DOCX, XLSX, PPT, PDF, images and more

Windows Authentication and Account Caching on Web Browser Auto-Logins


:P
On this page:
Edit this Post

Last week I ran into a nasty issue that had me seriously stumped. I've been working on an ASP.NET Core application that uses Windows Authentication to capture the network Active Directory login and needs access the user's AD and Windows group membership.

Seems easy enough - ASP.NET Core includes support for Windows Authentication including in Kestrel and on Windows this works as you would expect it to.

To set up Windows Authentication you need to add a Nuget package:

<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="3.0.0" />

and then hook it up in ConfigureServices():

services
    .AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();

and in Configure():

// Enable System Authentication
app.UseAuthentication(); 
app.UseAuthorization();
Middleware Order Matters

Make sure you hook up Windows Authentication .UseAuthentication() and .UseAuthorization after .AddRouting() but before any other middleware that uses authentication like MVC or Pages or StaticFiles. If the order is wrong, authentication won't work.

Once hooked up authentication works as you would expect it to: You can apply it via an [Authorize] attribute on a controller or you can simply check context.User.Identity for the Windows WindowsIdentity or WindowsPrincipal. You can also explicitly challenge with a 401 response. The authentication provider gives you the authentication status, user account info along with the all the Windows or Active Directory Groups the user is part of.

Simple enough.

Auto-Logons vs Explicit Logins: Different Results?

I've been working on an application that relies on ActiveDirectory Group membership, to validate access to modules and components and since I don't actually have an AD server running on my local setup I've been using local Windows groups. The behavior of these groups vs. AD groups is not very different. So while I explicitly created a few custom groups that I can work with in this application locally.

But I ran into a perplexing snag that took me a few days to track and eventually solve with the help of a Stack Overflow question I posted (more on this below).

Depending on how I logged into my local development Web site I was getting a different set of groups returned to me. Explicitly logging in with a browser dialog would net an accurate list of groups, but automatically getting logged in by Windows auto-login in Chromium browsers or classic Edge would only show me a truncated list.

Explicit Login


Figure 1 - An explicit login via Browser Login Dialog properly returns the new groups.

Automatically Logged in


Figure 2 - Result from an automatic login is missing the the custom groups.

Yikes what the heck is going on here? Two very different results for the same exact Windows User! Notice those custom groups I created for the application are not showing up in Figure 2.

Testing Forced Login

Windows by default is set up to use automatic logins. Chromium browsers (Chrome, Edgium, Brave, Vivaldi etc.) and classic Edge use this setting to automatically try and authenticate the current Windows User when an NTLM or Negotiate 401 request is received logging you in with your current Windows or AD account.

You can change this behavior and explicitly force Windows to always authenticate instead by using the Internet Settings from task bar, then digging into Local Intranet → Custom Level. At the bottom of the list you'll find an option to specify how Windows logins are handled:


Figure 3 - The Internet Settings dialog lets you customize how Windows gets your current Windows Login in a Browser

Note that FireFox doesn't do automatic Windows logins and always forces a browser dialog for explicitly logging in.

Watch for Cached Windows Logins

I'm going to spare you all the false starts I tried in trying to resolve this and cut straight to the solution which was pointed out to me on my Stack Overflow post by Gabriel Luci quite a few days after the initial question was posted. Thanks Gabriel!

The short of it is this: I created the new accounts listed in Figure 1, in my currently logged in Windows Profile. In other words - New Accounts!

When using automatic login it appears that Windows is using a cached account snapshot captured when you last logged on to Windows for the current session. This resulted in the missing groups shown in Figure 2, because the account snapshot apparently doesn't see these newly added accounts.

When Gabriel first pointed this out in the Stack Overflow post, I didn't believe it because:

  • I'd been fighting this issue for nearly week by then
  • I thought I had rebooted the machine

It turns out that apparently I did not reboot or log out. I did however, eventually explicitly log out of my Windows box, and logged back in, and lo and behold all the accounts are showing up now.

Updating Groups without a Logoff?

It is possible to refresh groups by essentially reissuing the Windows Login security ticket. There's a lot of info in this article:

How to refresh Groups Membership with User Logoff

The following commands are lifted from the above article. You can check for group membership of the current user with:

whoami /groups

or you can use:

gpresult /r

This is useful to see what your actual user account is actually seeing, vs what a manual logon sees.

The latter is very slow as it scours the network for domain servers, but it provides a lot of information about the user including the group membership as well as when the auth ticket was created. When I just ran this on my machine it showed a date nearly 2 weeks ago. Yikes.

For ActiveDirectory logins you use:

klist

to list logins, and

klist purge

to clear all logins which will force a new login next time you try to access a resource. In a Web Browser this will then force the browser dialog to pop up for explicit login which is then cached for subsequent auto-logins.

This works, but these tools are pretty obscure (I certainly never heard of them), but it's a possibility to perhaps integrate them via command line execution from within an application to refresh logins. Note all these commands don't require admin rights, so they can be run in user scope.

Summary

This is one of those things that makes a good deal of sense once you understand what's happening, but while it's happening it seems incredibly broken. In fact, I posted an issue on the ASP.NET Core repo for this, because I was sure this had to be a bug in how groups were handled - either in Windows or inside of ASP.NET Core. I went to extreme lengths to validate this with different scenarios - running with Kestrel, running with IIS Express, running under IIS proper.

In the end this is a problem in Windows behavior with a simple solution: Log out to see your new group memberships and other updated user account info.

This isn't ideal obviously and can easily bite you, because I suspect I'm not the only user who rarely logs out or reboots his machine these days. For me It's not uncommon to be logged in without an explicit log off for a few weeks at a time which is a long time to not refresh your account group settings.

In an application that means that if users are added to Windows or Active Directory Groups and your application depends on those new groups, you have to force users to log out and back in. This is problematic on several fronts -detectingg when that happens, and getting users to actually perform an annoying log off/log on cycle.

It's an edge case to be sure, but if you have long logged in accounts which is not uncommon these days, this issue might come to bite you too… now you know what to do 😃

Posted in ASP.NET Core  Windows  IIS  

The Voices of Reason


 

Rory Fewell
October 29, 2019

# re: Windows Authentication and Account Caching on Web Browser Auto-Logins

I think that has always been the case for AD accounts - it's certainly typical when I have adjusted groups on people's accounts (to say, allow them access to a mapped network drive) they have to log out and back in for the new groups to apply (and gain access to resources). Same goes for NTFS permissions.

The group memberships go along with the Kerberos ticket that is made at logon time, so logging out and logging back in issues a new ticket with the up-to-date memberships.


Rick Strahl
October 29, 2019

# re: Windows Authentication and Account Caching on Web Browser Auto-Logins

@Rory - sure I understand that, now.

The confusing thing about it is that the behavior is different whether you log in explicitly via the browser login dialog, or whether you are automatically logged in via the auto-login dialog. In hindsight that too makes sense, but if you don't know from experience how AD/Windows accounts and Kerberos tickets are managed it's easy to - as I did - jump to a completely wrong conclusion and think auth is broken 😃.


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2019