diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
index 4ee09824cf..9f1051fbd5 100644
--- a/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj
@@ -8,10 +8,6 @@
-
-
-
-
diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
index 61c064b376..327088d3e0 100644
--- a/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Components.Server/Microsoft/AspNetCore/Authentication/Cookies/CookieAuthenticationOptionsExtensions.cs
@@ -1,7 +1,9 @@
using System;
+using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Authentication.Cookies;
@@ -23,6 +25,8 @@ public static class CookieAuthenticationOptionsExtensions
if (principalContext.Principal != null && principalContext.Principal.Identity != null && principalContext.Principal.Identity.IsAuthenticated)
{
+ var logger = principalContext.HttpContext.RequestServices.GetRequiredService>();
+
var accessToken = principalContext.Properties.GetTokenValue("access_token");
if (!accessToken.IsNullOrWhiteSpace())
{
@@ -40,17 +44,36 @@ public static class CookieAuthenticationOptionsExtensions
Token = accessToken
});
- if (response.IsActive)
+ if (response.IsError)
{
+ logger.LogError(response.Error);
+ await SignOutAsync(principalContext);
+ return;
+ }
+
+ if (!response.IsActive)
+ {
+ logger.LogError("The access_token is not active.");
+ await SignOutAsync(principalContext);
return;
}
- }
- principalContext.RejectPrincipal();
- await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name);
+ logger.LogInformation("The access_token is active.");
+ }
+ else
+ {
+ logger.LogError("The access_token is not found in the cookie properties, Please make sure SaveTokens of OpenIdConnectOptions is set as true.");
+ await SignOutAsync(principalContext);
+ }
}
};
return options;
}
+
+ private async static Task SignOutAsync(CookieValidatePrincipalContext principalContext)
+ {
+ principalContext.RejectPrincipal();
+ await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name);
+ }
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs
index 430eddbcb4..835455795d 100644
--- a/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.cs
@@ -1,31 +1,96 @@
using System;
using System.Globalization;
+using System.Threading.Tasks;
+using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection;
public static class CookieAuthenticationOptionsExtensions
{
- public static CookieAuthenticationOptions CheckTokenExpiration(this CookieAuthenticationOptions options, TimeSpan? advance = null)
+ ///
+ /// Check the access_token is expired or inactive.
+ ///
+ public static CookieAuthenticationOptions CheckTokenExpiration(this CookieAuthenticationOptions options, string oidcAuthenticationScheme = "oidc", TimeSpan? advance = null, TimeSpan? validationInterval = null)
{
- advance ??= TimeSpan.FromMinutes(5);
+ advance ??= TimeSpan.FromMinutes(3);
+ validationInterval ??= TimeSpan.FromMinutes(1);
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 logger = principalContext.HttpContext.RequestServices.GetRequiredService>();
+
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))
+ if (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);
+ logger.LogInformation("The access_token is expired.");
+ await SignOutAsync(principalContext);
+ return;
+ }
+
+ if (principalContext.Properties.IssuedUtc != null)
+ {
+ if (DateTimeOffset.UtcNow.Subtract(principalContext.Properties.IssuedUtc.Value) > validationInterval)
+ {
+ logger.LogInformation($"Check the access_token is active every {validationInterval.Value.TotalSeconds} seconds.");
+ var accessToken = principalContext.Properties.GetTokenValue("access_token");
+ if (!accessToken.IsNullOrWhiteSpace())
+ {
+ var openIdConnectOptions = principalContext.HttpContext.RequestServices.GetRequiredService>().Get(oidcAuthenticationScheme);
+ if (openIdConnectOptions.Configuration == null && openIdConnectOptions.ConfigurationManager != null)
+ {
+ openIdConnectOptions.Configuration = await openIdConnectOptions.ConfigurationManager.GetConfigurationAsync(principalContext.HttpContext.RequestAborted);
+ }
+
+ var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
+ {
+ Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority.EnsureEndsWith('/') + "connect/introspect",
+ ClientId = openIdConnectOptions.ClientId,
+ ClientSecret = openIdConnectOptions.ClientSecret,
+ Token = accessToken
+ });
+
+ if (response.IsError)
+ {
+ logger.LogError(response.Error);
+ await SignOutAsync(principalContext);
+ return;
+ }
+
+ if (!response.IsActive)
+ {
+ logger.LogError("The access_token is not active.");
+ await SignOutAsync(principalContext);
+ return;
+ }
+
+ logger.LogInformation("The access_token is active.");
+ principalContext.ShouldRenew = true;
+ }
+ else
+ {
+ logger.LogError("The access_token is not found in the cookie properties, Please make sure SaveTokens of OpenIdConnectOptions is set as true.");
+ await SignOutAsync(principalContext);
+ }
+ }
}
}
};
+
return options;
}
+
+ private async static Task SignOutAsync(CookieValidatePrincipalContext principalContext)
+ {
+ principalContext.RejectPrincipal();
+ await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name);
+ }
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
index aa1090e204..0fe01e9f2b 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
+++ b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
@@ -26,6 +26,8 @@
+
+