Search code examples
asp.net-identityasp.net-core-2.0identityserver4razor-pages

How to get ASP.NET Identity authentication ticket expiry in Razor Page?


I'm using identityserver4 with ASP.NET Identity, with a cookie configured with SlidingExpiration = true and ExpireTimeSpan = 20 minutes. I would like to provide the user with a warning when they are about to timeout so am trying to access the ".expiry" value in the cookie.

So far I have been able to read an expiry time using the Razor code below. However this is failing to read the correct expiry time when the user refreshes their ticket. According to the Microsoft docs SlidingExpiration should provide my user with a new ticket if they refresh the page 10 minutes or more (>= 50% of ExpireTimeSpan) after getting a ticket. It does this fine, but when it does so the code below provides the old expiry time until the user refreshes the page for a second time!

@(DateTime.Parse(((await Context.AuthenticateAsync()).Properties.Items)[".expires"]))

What I want to know is how do I get the correct expiry time on the page generated when the new ticket is provided?


Solution

  • I've kind of solved my issue, I don't much like this solution as it's quite hacky. It does work though so I'm posting it here in case it is helpful. I'd much appreciate it if anyone can help me understand a better solution, I'll edit this answer or delete it in favour of another if/when that happens.

    I get the authentication ticket expiry in much the same way as in my question, then if there is less than 50% of my ExpireTimeSpan setting left I assume it would have renewed (a bit risky maybe but so far it's the best I've managed). I use this to calculate the assumed number of seconds remaining until timeout, then use this value when deciding when to show the user a warning.

    At the top of the Razor (partial):

    @using Microsoft.AspNetCore.Authentication;
    

    The important bit of my code (feel free to suggest improvements):

    secondsRemaining = "@(DateTime.Parse(((await AuthenticationHttpContextExtensions
                                                 .AuthenticateAsync(Context))
                                                 .Properties
                                                 .Items)[".expires"])
                         .Subtract(DateTime.Now)
                         .TotalSeconds)";
    // If secondsRemaining is less than half the expiry timespan then assume it will be re-issued
    if (secondsRemaining < timeoutSeconds / 2) {
        secondsRemaining = timeoutSeconds;
    }