diff --git a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalROptions.cs b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalROptions.cs
index 8ed3cffd2e..5791e05d8f 100644
--- a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalROptions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpSignalROptions.cs
@@ -1,11 +1,19 @@
-namespace Volo.Abp.AspNetCore.SignalR;
+using System;
+
+namespace Volo.Abp.AspNetCore.SignalR;
public class AbpSignalROptions
{
public HubConfigList Hubs { get; }
+ ///
+ /// Default: 5 seconds.
+ ///
+ public TimeSpan? CheckDynamicClaimsInterval { get; set; }
+
public AbpSignalROptions()
{
Hubs = new HubConfigList();
+ CheckDynamicClaimsInterval = TimeSpan.FromSeconds(5);
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/Authentication/AbpAuthenticationHubFilter.cs b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/Authentication/AbpAuthenticationHubFilter.cs
index c7b8c029cf..03fe720310 100644
--- a/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/Authentication/AbpAuthenticationHubFilter.cs
+++ b/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/Authentication/AbpAuthenticationHubFilter.cs
@@ -1,8 +1,10 @@
using System;
+using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.Security.Claims;
@@ -49,6 +51,20 @@ public class AbpAuthenticationHubFilter : IHubFilter
claimsPrincipal.Identity.IsAuthenticated &&
serviceProvider.GetRequiredService>().Value.IsDynamicClaimsEnabled)
{
+ var checkDynamicClaimsInterval = serviceProvider.GetRequiredService>().Value.CheckDynamicClaimsInterval;
+ if (checkDynamicClaimsInterval.HasValue &&
+ hubCallerContext.Items.TryGetValue(nameof(HandleDynamicClaimsPrincipalAsync), out var lastCheckDynamicClaimsTime) &&
+ lastCheckDynamicClaimsTime is DateTime lastCheckDynamicClaimsTimeValue)
+ {
+ if (DateTime.UtcNow.Subtract(lastCheckDynamicClaimsTimeValue) < checkDynamicClaimsInterval.Value)
+ {
+ // Dynamic claims are not checked because the interval has not passed yet.
+ return;
+ }
+ }
+
+ hubCallerContext.Items[nameof(HandleDynamicClaimsPrincipalAsync)] = DateTime.UtcNow;
+
claimsPrincipal = claimsPrincipal.Identity is ClaimsIdentity identity
? new ClaimsPrincipal(new ClaimsIdentity(claimsPrincipal.Claims, claimsPrincipal.Identity.AuthenticationType, identity.NameClaimType, identity.RoleClaimType))
: new ClaimsPrincipal(new ClaimsIdentity(claimsPrincipal.Claims, claimsPrincipal.Identity.AuthenticationType));