Can we personalize Session Timeout for Roles in ASP.NET MVC 5
Asked Answered
O

2

7

The idea is to set different values of Session Timeout for different User Roles in ASP.NET MVC 5 and ASP.NET Identity.

Is it possible to do?

Overshine answered 20/10, 2014 at 13:24 Comment(0)
C
2

Based on their role you could set the timeout, i.e.

HttpContext.Current.Session.Timeout = 20;

Going by your previous question you want to do this dynamically. You could store and update the times themselves in session and set for each role on OnActionExecuting of a base controller.

    if (User.IsInRole("Admin"))
    {
        filterContext.HttpContext.Session.Timeout = 
(int)filterContext.HttpContext.Session["AdminTimeoutThatYouSetSomewhereElseGlobally"];
    }
Circumambient answered 20/10, 2014 at 13:38 Comment(3)
Will it work for ASP.NET MVC 5 and ASP.NET Identity?Overshine
will work for Mvc5. How are you implementing Identity? Have you got a base controller? It should be fine. Your check against the user might be different but the session is the same.Circumambient
Will only work if you are using session, which is not enabled by default, AFAIKRabies
C
5

If you are trying to boot admins out sooner than regular users, here is my stub on this in Identity.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    // other stuff
    Provider = new CookieAuthenticationProvider
    {
        // this function is executed every http request and executed very early in the pipeline
        // and here you have access to cookie properties and other low-level stuff. 
        // makes sense to have the invalidation here
        OnValidateIdentity = async context =>
        {
            // invalidate user cookie if user's security stamp have changed
            var invalidateBySecirityStamp = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager));
            await invalidateBySecirityStamp.Invoke(context);

            // check if user is in admin role
            var isAdmin = context.Identity.Claims.Any(c => c.Type == ClaimTypes.Role && c.Value == "AdminRoleName");

            // check if enough time has passed to invalidate cookie
            var currentUtc = DateTimeOffset.UtcNow;
            if (context.Options != null && context.Options.SystemClock != null)
            {
                currentUtc = context.Options.SystemClock.UtcNow;
            }

            var issuedUtc = context.Properties.IssuedUtc;
            var bootThemOut = (issuedUtc == null);
            if (issuedUtc != null)
            {
                var timeElapsed = currentUtc.Subtract(issuedUtc.Value);
                bootThemOut = timeElapsed > TimeSpan.FromMinutes(3); // invalidate admin cookies in 3 minutes
            }

            if (isAdmin && bootThemOut)
            {
                context.RejectIdentity();
                context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
            }
        }
    }
});            
Carlock answered 20/10, 2014 at 22:18 Comment(4)
I found this article gave me a better understanding of the answer above re: ASPNET Identity Cookie Authentication Timeouts timeouts for use with Identity and MVC5: jamessturtevant.com/posts/…Rabies
Howo can we achieve SlidingExpiration = true behavior using this solution?Shaunda
I read the post and one step says "Since the User issued a request after the validateInterval at location A they will be signed-out and prompted for their credentials again.". What if we don't want to wait until after the validateInterval? If a user changes their password at location A, I would like the user to be forced to login immediately at location B. Could you help with this please?Simper
@Simper Well, on password update change the SecurityStamp field and set the validateInterval to be small enough to match your "immediately" requirement. Though I don't recommend setting it to less than a few seconds.Carlock
C
2

Based on their role you could set the timeout, i.e.

HttpContext.Current.Session.Timeout = 20;

Going by your previous question you want to do this dynamically. You could store and update the times themselves in session and set for each role on OnActionExecuting of a base controller.

    if (User.IsInRole("Admin"))
    {
        filterContext.HttpContext.Session.Timeout = 
(int)filterContext.HttpContext.Session["AdminTimeoutThatYouSetSomewhereElseGlobally"];
    }
Circumambient answered 20/10, 2014 at 13:38 Comment(3)
Will it work for ASP.NET MVC 5 and ASP.NET Identity?Overshine
will work for Mvc5. How are you implementing Identity? Have you got a base controller? It should be fine. Your check against the user might be different but the session is the same.Circumambient
Will only work if you are using session, which is not enabled by default, AFAIKRabies

© 2022 - 2024 — McMap. All rights reserved.