From 029e7ac25bfadbc65a28c00cdf3680b168d84a8d Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 3 Apr 2024 11:27:20 +0800 Subject: [PATCH] Add `WebAssemblyAuthenticationStateProvider`. --- ...BlazorWebAppServiceCollectionExtensions.cs | 3 - ...bpAspNetCoreComponentsWebAssemblyModule.cs | 19 +++++++ .../WebAssemblyAuthenticationStateProvider.cs | 56 +++++++++++++++++++ ...blyCachedApplicationConfigurationClient.cs | 12 +++- .../WebAssemblyCurrentPrincipalAccessor.cs | 23 -------- ...AssemblyRemoteCurrentPrincipalAccessor.cs} | 8 +-- 6 files changed, 90 insertions(+), 31 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyAuthenticationStateProvider.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs rename framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/{WebApp/RemoteCurrentPrincipalAccessor.cs => WebAssemblyRemoteCurrentPrincipalAccessor.cs} (91%) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpBlazorWebAppServiceCollectionExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpBlazorWebAppServiceCollectionExtensions.cs index fe2acfc13b..1bcc1c1f45 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpBlazorWebAppServiceCollectionExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/Extensions/DependencyInjection/AbpBlazorWebAppServiceCollectionExtensions.cs @@ -4,7 +4,6 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp; using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; using Volo.Abp.Http.Client.Authentication; -using Volo.Abp.Security.Claims; namespace Microsoft.Extensions.DependencyInjection; @@ -16,7 +15,6 @@ public static class AbpBlazorWebAppServiceCollectionExtensions services.AddSingleton(); services.Replace(ServiceDescriptor.Transient()); - services.Replace(ServiceDescriptor.Transient()); return services; } @@ -27,7 +25,6 @@ public static class AbpBlazorWebAppServiceCollectionExtensions services.AddScoped(); services.Replace(ServiceDescriptor.Singleton()); - services.Replace(ServiceDescriptor.Transient()); return services; } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs index b16286c19f..7c0c79a174 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs @@ -1,6 +1,8 @@ using System; using System.Globalization; +using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp.AspNetCore.Components.Web; @@ -47,6 +49,23 @@ public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule .AddProvider(new AbpExceptionHandlingLoggerProvider(context.Services)); } + public override void PostConfigureServices(ServiceConfigurationContext context) + { + var msAuthenticationStateProvider = context.Services.FirstOrDefault(x => x.ServiceType == typeof(AuthenticationStateProvider)); + if (msAuthenticationStateProvider != null && msAuthenticationStateProvider.ImplementationType != null) + { + var webAssemblyAuthenticationStateProviderType = typeof(WebAssemblyAuthenticationStateProvider<,,>).MakeGenericType( + msAuthenticationStateProvider.ImplementationType.GenericTypeArguments[0], + msAuthenticationStateProvider.ImplementationType.GenericTypeArguments[1], + msAuthenticationStateProvider.ImplementationType.GenericTypeArguments[2]); + + context.Services.AddScoped(webAssemblyAuthenticationStateProviderType, webAssemblyAuthenticationStateProviderType); + + context.Services.Remove(msAuthenticationStateProvider); + context.Services.AddScoped(typeof(AuthenticationStateProvider), sp => sp.GetRequiredService(webAssemblyAuthenticationStateProviderType)); + } + } + public override void OnApplicationInitialization(ApplicationInitializationContext context) { AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context)); diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyAuthenticationStateProvider.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyAuthenticationStateProvider.cs new file mode 100644 index 0000000000..dc6b3d3536 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyAuthenticationStateProvider.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly; + +public class WebAssemblyAuthenticationStateProvider : RemoteAuthenticationService + where TRemoteAuthenticationState : RemoteAuthenticationState + where TProviderOptions : new() + where TAccount : RemoteUserAccount +{ + protected WebAssemblyCachedApplicationConfigurationClient WebAssemblyCachedApplicationConfigurationClient { get; } + + [Obsolete] + public WebAssemblyAuthenticationStateProvider( + IJSRuntime jsRuntime, + IOptionsSnapshot> options, + NavigationManager navigation, + AccountClaimsPrincipalFactory accountClaimsPrincipalFactory, + ILogger> logger, + WebAssemblyCachedApplicationConfigurationClient webAssemblyCachedApplicationConfigurationClient) + : base(jsRuntime, options, navigation, accountClaimsPrincipalFactory) + { + WebAssemblyCachedApplicationConfigurationClient = webAssemblyCachedApplicationConfigurationClient; + } + + public WebAssemblyAuthenticationStateProvider( + IJSRuntime jsRuntime, + IOptionsSnapshot> options, + NavigationManager navigation, + AccountClaimsPrincipalFactory accountClaimsPrincipalFactory, + ILogger>? logger, + ILogger> logger1, + WebAssemblyCachedApplicationConfigurationClient webAssemblyCachedApplicationConfigurationClient) + : base(jsRuntime, options, navigation, accountClaimsPrincipalFactory, logger) + { + WebAssemblyCachedApplicationConfigurationClient = webAssemblyCachedApplicationConfigurationClient; + } + + public async override Task GetAuthenticationStateAsync() + { + var state = await base.GetAuthenticationStateAsync(); + var applicationConfigurationDto = await WebAssemblyCachedApplicationConfigurationClient.GetAsync(); + if (state.User.Identity != null && state.User.Identity.IsAuthenticated && !applicationConfigurationDto.CurrentUser.IsAuthenticated) + { + await WebAssemblyCachedApplicationConfigurationClient.InitializeAsync(); + } + + return state; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs index 1a0b7c741b..32b7f875ec 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Microsoft.JSInterop; using Volo.Abp.AspNetCore.Components.Web.Security; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies; @@ -20,18 +21,22 @@ public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicatio protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; } + protected IJSRuntime JSRuntime { get; } + public WebAssemblyCachedApplicationConfigurationClient( AbpApplicationConfigurationClientProxy applicationConfigurationClientProxy, ApplicationConfigurationCache cache, ICurrentTenantAccessor currentTenantAccessor, AbpApplicationLocalizationClientProxy applicationLocalizationClientProxy, - ApplicationConfigurationChangedService applicationConfigurationChangedService) + ApplicationConfigurationChangedService applicationConfigurationChangedService, + IJSRuntime jsRuntime) { ApplicationConfigurationClientProxy = applicationConfigurationClientProxy; Cache = cache; CurrentTenantAccessor = currentTenantAccessor; ApplicationLocalizationClientProxy = applicationLocalizationClientProxy; ApplicationConfigurationChangedService = applicationConfigurationChangedService; + JSRuntime = jsRuntime; } public virtual async Task InitializeAsync() @@ -53,6 +58,11 @@ public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicatio Cache.Set(configurationDto); + if (!configurationDto.CurrentUser.IsAuthenticated) + { + await JSRuntime.InvokeVoidAsync("sessionStorage.clear"); + } + ApplicationConfigurationChangedService.NotifyChanged(); CurrentTenantAccessor.Current = new BasicTenantInfo( diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs deleted file mode 100644 index 9f1eb5d0b9..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCurrentPrincipalAccessor.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Security.Claims; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.AspNetCore.Components.Web.Security; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Security.Claims; - -namespace Volo.Abp.AspNetCore.Components.WebAssembly; - -public class WebAssemblyCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITransientDependency -{ - protected AbpComponentsClaimsCache ClaimsCache { get; } - - public WebAssemblyCurrentPrincipalAccessor( - IClientScopeServiceProviderAccessor clientScopeServiceProviderAccessor) - { - ClaimsCache = clientScopeServiceProviderAccessor.ServiceProvider.GetRequiredService(); - } - - protected override ClaimsPrincipal GetClaimsPrincipal() - { - return ClaimsCache.Principal; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebApp/RemoteCurrentPrincipalAccessor.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyRemoteCurrentPrincipalAccessor.cs similarity index 91% rename from framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebApp/RemoteCurrentPrincipalAccessor.cs rename to framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyRemoteCurrentPrincipalAccessor.cs index 6667785ad2..e96e315144 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebApp/RemoteCurrentPrincipalAccessor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyRemoteCurrentPrincipalAccessor.cs @@ -3,13 +3,13 @@ using System.Security.Claims; using Volo.Abp.DependencyInjection; using Volo.Abp.Security.Claims; -namespace Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; +namespace Volo.Abp.AspNetCore.Components.WebAssembly; -public class RemoteCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITransientDependency +public class WebAssemblyRemoteCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITransientDependency { protected ApplicationConfigurationCache ApplicationConfigurationCache { get; } - public RemoteCurrentPrincipalAccessor(ApplicationConfigurationCache applicationConfigurationCache) + public WebAssemblyRemoteCurrentPrincipalAccessor(ApplicationConfigurationCache applicationConfigurationCache) { ApplicationConfigurationCache = applicationConfigurationCache; } @@ -84,6 +84,6 @@ public class RemoteCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITra } } - return new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType: nameof(RemoteCurrentPrincipalAccessor))); + return new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType: nameof(WebAssemblyRemoteCurrentPrincipalAccessor))); } }