7

I’m encountering an issue wherein Windows authenticated user roles appear to be cached and are not updated until I restart the application. While a user's roles will not change often they do change and can change before an application restart is performed.

I am hosting my ASP.NET Core 2 application on IIS via Kestrel and the ASP.NET Core Module. Via the AuthorizeFilter I have a global policy which requires authenticated users. Users are not prompted for credentials but are instead authenticated via integrated Windows Authentication. Below are snippets of my application configuration that pertain to server host configuration, authentication and authorization:

Snippets from Program.cs

private static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
               .UseKestrel(options =>
                           {
                               options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30); 
                           })
               .UseIISIntegration()
               .Build();

Snippets from Startup.cs

Authentication Configuration

services.AddAuthentication(options =>
                       {
                           options.DefaultScheme = IISDefaults.AuthenticationScheme;
                           options.DefaultForbidScheme = IISDefaults.AuthenticationScheme;
                       });

Authorization Configuration

services.AddAuthorization(options =>
         {
             options.AddPolicy("RequireAuthenticatedUser",
                               policyBuilder => policyBuilder.RequireAuthenticatedUser());
         });

Addition of Global AuthorizeFilter:

services.AddMvc(mvcOptions =>
                {
                  mvcOptions.Filters.Add(new AuthorizeFilter("RequireAuthenticatedUser"));
                });

Snippet from launchSettings.json

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:4100",
      "sslPort": 0
    }
  }
}

All of this works wonderfully and users are required to authenticate and I am able to retrieve their Active Directory roles. Sadly, when those roles change without an application restart I am unable to get an updated list of roles. Meaning that users who should have access do not and those that should no longer have access still do. All of my role checking is based on the ClaimsPrincipal.IsInRole("xyz"), which remains stagnant from when the user first authenticated. However, if I use System.DirectoryServices.AccountManagement to check the user's current roles within Active Directory they are clearly updated (for production want to use built in functionality and don't want to resort to this).

What configuration changes, cache invalidation or session reset do I need to perform to ensure that when a user's AD roles change my application will reflect their current roles?

ahsteele
  • 26,243
  • 28
  • 134
  • 248
  • 1
    Is this using integrated windows auth or do users login with their windows credentials? The claims for a user could be cached when the user is authenticated so perhaps you could reissue them via a fresh `HttpContext.SignInAsync()`? – Neil May 21 '18 at 03:42
  • 2
    In Windows, Filesystem permissions apply at the moment you hit "Apply". But Group membership forms part of the user's kerberos token as far as I'm aware. This can only be generated on login which is why you must have users to logout and back in again for the new group memberships to take effect. – VahidN May 21 '18 at 06:47
  • @Neil my application is making use of integrated windows authentication. I've played with `HttpContext.SignInAsync()`, but might be putting it in the wrong place in the pipeline as it hasn't changed anything. The whole issue smacks of needing to setup a timeout or forcing a refresh. – ahsteele May 21 '18 at 16:00
  • Is this of any help? https://stackoverflow.com/questions/6690822/how-can-i-ensure-that-isinrole-checks-are-not-using-cached-credentials – Tarun Lalwani May 21 '18 at 19:17
  • Windows Auth is cached by IIS at the connection level. At a minimum the user would need to close the connection to force a re-auth. See authPersistNonNTLM and authPersistSingleRequest at https://learn.microsoft.com/en-us/iis/configuration/system.webserver/security/authentication/windowsauthentication/. What happens if they close the browser (and connections) and try again? That said, I've observed the same as VahidN, the user often needs to log out of the machine and log back in before group membership changes take effect. – Tratcher May 22 '18 at 14:54
  • If the user runs a *klist purge* in a command prompt and then re-accesses the application, the roles searched will show the latest update. This does not require a user logout. If you can bake in a *klist purge* at the beginning of your authentication sequence you'll be good to go. On the client side, you can start your application with batch file that runs the *klist purge*, then launches the application itself right after. – T-Heron May 27 '18 at 15:25

0 Answers0