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 b18fdab82e..a9f2cecef9 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 @@ -8,6 +8,7 @@ using Volo.Abp.AspNetCore.Components.Web.ExceptionHandling; using Volo.Abp.AspNetCore.Components.Web.Security; using Volo.Abp.AspNetCore.Mvc.Client; using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; using Volo.Abp.Http.Client; using Volo.Abp.Modularity; using Volo.Abp.Threading; @@ -18,7 +19,8 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly; [DependsOn( typeof(AbpAspNetCoreMvcClientCommonModule), typeof(AbpUiModule), - typeof(AbpAspNetCoreComponentsWebModule) + typeof(AbpAspNetCoreComponentsWebModule), + typeof(AbpEventBusModule) )] public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs new file mode 100644 index 0000000000..252012feb5 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; +using Volo.Abp.Http; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly; + +public class ClientProxyExceptionEventHandler : ILocalEventHandler, ITransientDependency +{ + protected NavigationManager NavigationManager { get; } + protected IAccessTokenProvider AccessTokenProvider { get; } + + public ClientProxyExceptionEventHandler(NavigationManager navigationManager, IAccessTokenProvider accessTokenProvider) + { + NavigationManager = navigationManager; + AccessTokenProvider = accessTokenProvider; + } + + public virtual async Task HandleEventAsync(ClientProxyExceptionEventData eventData) + { + if (eventData.StatusCode == 401) + { + var result = await AccessTokenProvider.RequestAccessToken(); + if (result.Status != AccessTokenResultStatus.Success) + { + NavigationManager.NavigateToLogout("authentication/logout"); + return; + } + + result.TryGetToken(out var token); + if (token != null && DateTimeOffset.Now >= token.Expires.AddMinutes(-5)) + { + NavigationManager.NavigateToLogout("authentication/logout"); + } + } + } +} diff --git a/framework/src/Volo.Abp.Http.Abstractions/Volo/Abp/Http/ClientProxyExceptionEventData.cs b/framework/src/Volo.Abp.Http.Abstractions/Volo/Abp/Http/ClientProxyExceptionEventData.cs new file mode 100644 index 0000000000..1bc17c7b65 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Abstractions/Volo/Abp/Http/ClientProxyExceptionEventData.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.Http; + +public class ClientProxyExceptionEventData +{ + public int? StatusCode { get; set; } + + public string ReasonPhrase { get; set; } +} diff --git a/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj b/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj index 26708da6b7..0b4e3ad76f 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj +++ b/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj @@ -20,6 +20,7 @@ + diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs index a164f9587e..dc14ee4203 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Castle; +using Volo.Abp.EventBus; using Volo.Abp.Modularity; using Volo.Abp.MultiTenancy; using Volo.Abp.Threading; @@ -17,7 +18,8 @@ namespace Volo.Abp.Http.Client; typeof(AbpMultiTenancyModule), typeof(AbpValidationModule), typeof(AbpExceptionHandlingModule), - typeof(AbpRemoteServicesModule) + typeof(AbpRemoteServicesModule), + typeof(AbpEventBusModule) )] public class AbpHttpClientModule : AbpModule { diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyBase.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyBase.cs index 8c0ab4f538..5c1d893bfd 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyBase.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -10,6 +10,7 @@ using Microsoft.Extensions.Options; using Microsoft.Extensions.Primitives; using Volo.Abp.Content; using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Local; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.Http.Client.Proxying; using Volo.Abp.Http.Modeling; @@ -39,6 +40,7 @@ public class ClientProxyBase : ITransientDependency protected ClientProxyRequestPayloadBuilder ClientProxyRequestPayloadBuilder => LazyServiceProvider.LazyGetRequiredService(); protected ClientProxyUrlBuilder ClientProxyUrlBuilder => LazyServiceProvider.LazyGetRequiredService(); protected ICurrentApiVersionInfo CurrentApiVersionInfo => LazyServiceProvider.LazyGetRequiredService(); + protected ILocalEventBus LocalEventBus => LazyServiceProvider.LazyGetRequiredService(); protected virtual async Task RequestAsync(string methodName, ClientProxyRequestTypeValue arguments = null) { @@ -66,7 +68,7 @@ public class ClientProxyBase : ITransientDependency var actionArguments = action.Parameters.GroupBy(x => x.NameOnMethod).ToList(); if (action.SupportedVersions.Any()) - { + { //TODO: make names configurable actionArguments.RemoveAll(x => x.Key == "api-version" || x.Key == "apiVersion"); } @@ -216,6 +218,12 @@ public class ClientProxyBase : ITransientDependency protected virtual async Task ThrowExceptionForResponseAsync(HttpResponseMessage response) { + await LocalEventBus.PublishAsync(new ClientProxyExceptionEventData() + { + StatusCode = (int?)response?.StatusCode, + ReasonPhrase = response?.ReasonPhrase + }); + if (response.Headers.Contains(AbpHttpConsts.AbpErrorFormat)) { RemoteServiceErrorResponse errorResponse;