Skip to content

Commit

Permalink
Merge pull request #19742 from abpframework/CheckDynamicClaimsInterval
Browse files Browse the repository at this point in the history
Checking dynamic claims at intervals rather than every time.
  • Loading branch information
EngincanV authored May 8, 2024
2 parents 5ceed1a + ffc94a2 commit 669406f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
namespace Volo.Abp.AspNetCore.SignalR;
using System;

namespace Volo.Abp.AspNetCore.SignalR;

public class AbpSignalROptions
{
public HubConfigList Hubs { get; }

/// <summary>
/// Default: 5 seconds.
/// </summary>
public TimeSpan? CheckDynamicClaimsInterval { get; set; }

public AbpSignalROptions()
{
Hubs = new HubConfigList();
CheckDynamicClaimsInterval = TimeSpan.FromSeconds(5);
}
}
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -14,7 +16,7 @@ public class AbpAuthenticationHubFilter : IHubFilter
{
var currentPrincipalAccessor = invocationContext.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
var claimsPrincipal = invocationContext.Context.User;
await HandleDynamicClaimsPrincipalAsync(claimsPrincipal, invocationContext.ServiceProvider, invocationContext.Context);
await HandleDynamicClaimsPrincipalAsync(claimsPrincipal, invocationContext.ServiceProvider, invocationContext.Context, false);
using (currentPrincipalAccessor.Change(claimsPrincipal!))
{
return await next(invocationContext);
Expand All @@ -25,7 +27,7 @@ public virtual async Task OnConnectedAsync(HubLifetimeContext context, Func<HubL
{
var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
var claimsPrincipal = context.Context.User;
await HandleDynamicClaimsPrincipalAsync(claimsPrincipal, context.ServiceProvider, context.Context);
await HandleDynamicClaimsPrincipalAsync(claimsPrincipal, context.ServiceProvider, context.Context, true);
using (currentPrincipalAccessor.Change(claimsPrincipal!))
{
await next(context);
Expand All @@ -36,24 +38,43 @@ public virtual async Task OnDisconnectedAsync(HubLifetimeContext context, Except
{
var currentPrincipalAccessor = context.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
var claimsPrincipal = context.Context.User;
await HandleDynamicClaimsPrincipalAsync(claimsPrincipal, context.ServiceProvider, context.Context);
await HandleDynamicClaimsPrincipalAsync(claimsPrincipal, context.ServiceProvider, context.Context, true);
using (currentPrincipalAccessor.Change(claimsPrincipal!))
{
await next(context, exception);
}
}

protected virtual async Task HandleDynamicClaimsPrincipalAsync(ClaimsPrincipal? claimsPrincipal, IServiceProvider serviceProvider, HubCallerContext hubCallerContext)
protected virtual async Task HandleDynamicClaimsPrincipalAsync(ClaimsPrincipal? claimsPrincipal, IServiceProvider serviceProvider, HubCallerContext hubCallerContext, bool skipCheckDynamicClaimsInterval)
{
if (claimsPrincipal?.Identity != null &&
claimsPrincipal.Identity.IsAuthenticated &&
serviceProvider.GetRequiredService<IOptions<AbpClaimsPrincipalFactoryOptions>>().Value.IsDynamicClaimsEnabled)
serviceProvider.GetRequiredService<IOptions<AbpClaimsPrincipalFactoryOptions>>().Value
.IsDynamicClaimsEnabled)
{
var checkDynamicClaimsInterval = serviceProvider.GetRequiredService<IOptions<AbpSignalROptions>>().Value.CheckDynamicClaimsInterval;
if (!skipCheckDynamicClaimsInterval &&
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));
? new ClaimsPrincipal(new ClaimsIdentity(claimsPrincipal.Claims,
claimsPrincipal.Identity.AuthenticationType, identity.NameClaimType, identity.RoleClaimType))
: new ClaimsPrincipal(new ClaimsIdentity(claimsPrincipal.Claims,
claimsPrincipal.Identity.AuthenticationType));

claimsPrincipal = await serviceProvider.GetRequiredService<IAbpClaimsPrincipalFactory>().CreateDynamicAsync(claimsPrincipal);
claimsPrincipal = await serviceProvider.GetRequiredService<IAbpClaimsPrincipalFactory>()
.CreateDynamicAsync(claimsPrincipal);
if (claimsPrincipal.Identity?.IsAuthenticated == false)
{
hubCallerContext.Abort();
Expand Down

0 comments on commit 669406f

Please sign in to comment.