From bceae5ba3a97c8937a5bdcfde0fae18c6242fbaa Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 8 May 2023 17:17:48 +0800 Subject: [PATCH] Check token expiration. We need to refresh the current user(`ThreadCurrentPrincipal`) --- .../CookieAuthenticationOptionsExtensions.cs | 31 +++++++++++++++++++ .../MyProjectNameWebModule.cs | 3 +- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs new file mode 100644 index 0000000000..430eddbcb4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs @@ -0,0 +1,31 @@ +using System; +using System.Globalization; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; + +namespace Microsoft.Extensions.DependencyInjection; + +public static class CookieAuthenticationOptionsExtensions +{ + public static CookieAuthenticationOptions CheckTokenExpiration(this CookieAuthenticationOptions options, TimeSpan? advance = null) + { + advance ??= TimeSpan.FromMinutes(5); + var originalHandler = options.Events.OnValidatePrincipal; + options.Events.OnValidatePrincipal = async principalContext => + { + originalHandler?.Invoke(principalContext); + if (principalContext.Principal != null && principalContext.Principal.Identity != null && principalContext.Principal.Identity.IsAuthenticated) + { + var tokenExpiresAt = principalContext.Properties.Items[".Token.expires_at"]; + if (tokenExpiresAt != null && + DateTimeOffset.TryParseExact(tokenExpiresAt, "o", null, DateTimeStyles.RoundtripKind, out var expiresAt) && + expiresAt < DateTimeOffset.UtcNow.Subtract(advance.Value)) + { + principalContext.RejectPrincipal(); + await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name); + } + } + }; + return options; + } +} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs index 55302dde61..8e8ac6c694 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs @@ -145,6 +145,7 @@ public class MyProjectNameWebModule : AbpModule .AddCookie("Cookies", options => { options.ExpireTimeSpan = TimeSpan.FromDays(365); + options.CheckTokenExpiration(); }) .AddAbpOpenIdConnect("oidc", options => { @@ -232,7 +233,7 @@ public class MyProjectNameWebModule : AbpModule dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "MyProjectName-Protection-Keys"); } } - + private void ConfigureDistributedLocking( ServiceConfigurationContext context, IConfiguration configuration)