2

I'm working on a web application that I recently migrated from a custom authentication solution to ASP.NET Identity. In some sections of our app, long processes are performed that can take up to an hour to run. Under normal circumstances, we want users to be automatically logged out after 30 minutes of non-activity. However, for screens where long processes occur, we want to widen the automatic logout window so that they don't get kicked out before the process completes. I'm currently struggling with how to accomplish this with Identity. I am currently using the following code in my Startup.Auth.cs file:

public partial class Startup
{
    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301883
    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Login.aspx"),
            ExpireTimeSpan = TimeSpan.FromMinutes(30),
            SlidingExpiration = true,
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity =
                    SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                        TimeSpan.FromMinutes(30),
                        (manager, user) => user.GenerateUserIdentityAsync(manager),
                        userIdentity => userIdentity.GetUserId<int>())
            }
        });
    }
}

I currently don't see any way to modify the ExpireTimeSpan value after ConfigureAuth has already been called. I hope to be able to change the value in the Page_Load event handler from a Web Form page. Does anyone know of a way?

Chad
  • 21
  • 6
  • would it be an option to just make an ajax call? so that the sessions is being accessed ? – alexo Dec 03 '14 at 21:24
  • @alexo: That's an interesting option. I don't know why I hadn't considered that. I think I'll keep it in my back pocket in case I don't find a method to change the authentication expire time span setting itself. – Chad Dec 03 '14 at 21:49
  • the problem is that, if you change it in one place, its gonna be changed everywhere, thats kinda global from my knowledge. so you might not want this to happen for other pages – alexo Dec 03 '14 at 22:12
  • @alexo: It is a global setting, but it can be changed on each page load. For example, I could have the master page set the ExpireTimeSpan to it's default value on each page load, and then allow that value to be overridden on page load by any page that wants it to be different. – Chad Dec 03 '14 at 22:33
  • when you mean global, you mean global at session level or at server level? because if its server level and you change it in one session for a specific user, its going to be changed for other users as well. And as i know, its global at server level, and if that's the behavior you want, well then that's the answer ? – alexo Dec 04 '14 at 07:56
  • @alexo: Oh. I did not realize that you were talking about global on a server level. That is not the behavior I want. Thanks for bringing that to my attention – Chad Dec 05 '14 at 01:51

1 Answers1

0

Inside OnValidateIdentity

aka:

OnValidateIdentity = delegate(CookieValidateIdentityContext context) {
            var stampValidator = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                getUserIdCallback: (id) => (id.GetUserId<int>())
            );
            Task result = stampValidator.Invoke(context);

            int my_custom_minutes = 60; // run your logic here.
                // set it at GLOBAL level for all (future) users.
                context.Options.ExpireTimeSpan = TimeSpan.FromMinutes( my_custom_minutes );
                // set it for the current user only.
                context.Properties.ExpiresUtc = context.Properties.IssuedUtc.Value.AddMinutes( my_custom_minutes );

            return result;
}
Barry
  • 362
  • 3
  • 14
  • It looks like your solution gives a an expiration to specific users, but it lasts across the whole session. Let me know that that's right. What I was looking for was the ability to arbitrarily extend the timeout. For example, we want to extend the timeout while viewing specific pages only. On PageA.aspx, extend timeout to 1 hour. – Chad Mar 28 '18 at 19:02
  • Should be able to access HttpContext, so you could check the request url for a page match, and extend it for current user. If you are wanting to extend it only for the duration of the page view, and not the whole asp user session, you'd have to somehow (I'd use claims) track the remaining time when your detected page was first loaded, and later, when any other page is loaded, subtract the current remaining time (altered by previous logic) by the amount stored at that time (via claim as it were). Not sure if that helps, but the above code is only way I know of to change it dynamically – Barry Apr 02 '18 at 21:20