Browse Source

Merge pull request #19563 from abpframework/liangshiwei/authenticationSessionstate

Add `AbpAuthenticationSessionState` to logout from other tabs
pull/19605/head
oykuermann 2 years ago
committed by GitHub
parent
commit
272f06c6b2
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalScriptContributor.cs
  2. 11
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/AbpAspNetCoreComponentsWebThemingModule.cs
  3. 8
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpAuthenticationOptions.cs
  4. 10
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ILocalStorageService.cs
  5. 31
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/LocalStorageService.cs
  6. 59
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpAuthenticationState.cs
  7. 17
      framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/js/authentication-state-listener.js
  8. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ComponentsComponentsBundleContributor.cs
  9. 10
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
  10. 7
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs
  11. 2
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/wwwroot/global.js
  12. 6
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Menus/MyProjectNameMenuContributor.cs
  13. 24
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/wwwroot/global.js
  14. 24
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/wwwroot/global.js
  15. 24
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/wwwroot/global.js
  16. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/App.razor
  17. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/wwwroot/global.css
  18. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/wwwroot/global.js
  19. 4
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/App.razor

1
framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalScriptContributor.cs

@ -15,5 +15,6 @@ public class BlazorGlobalScriptContributor : BundleContributor
context.Files.AddIfNotContains("/_framework/blazor.server.js");
}
context.Files.AddIfNotContains("/_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js");
context.Files.AddIfNotContains("/_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/authentication-state-listener.js");
}
}

11
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/AbpAspNetCoreComponentsWebThemingModule.cs

@ -1,4 +1,5 @@
using Volo.Abp.BlazoriseUI;
using Volo.Abp.AspNetCore.Components.Web.Security;
using Volo.Abp.BlazoriseUI;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;
@ -10,5 +11,11 @@ namespace Volo.Abp.AspNetCore.Components.Web.Theming;
)]
public class AbpAspNetCoreComponentsWebThemingModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDynamicLayoutComponentOptions>(options =>
{
options.Components.Add(typeof(AbpAuthenticationState), null);
});
}
}

8
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpAuthenticationOptions.cs

@ -0,0 +1,8 @@
namespace Volo.Abp.AspNetCore.Components.Web;
public class AbpAuthenticationOptions
{
public string LoginUrl { get; set; } = "Account/Login";
public string LogoutUrl { get; set; } = "Account/Logout";
}

10
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ILocalStorageService.cs

@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web;
public interface ILocalStorageService
{
public ValueTask SetItemAsync(string key, string value);
public ValueTask<string> GetItemAsync(string key);
public ValueTask RemoveItemAsync(string key);
}

31
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/LocalStorageService.cs

@ -0,0 +1,31 @@
using System.Threading.Tasks;
using Microsoft.JSInterop;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web;
[Dependency(ReplaceServices = true)]
public class LocalStorageService : ILocalStorageService, ITransientDependency
{
public IJSRuntime JsRuntime { get; }
public LocalStorageService(IJSRuntime jsRuntime)
{
JsRuntime = jsRuntime;
}
public async ValueTask SetItemAsync(string key, string value)
{
await JsRuntime.InvokeVoidAsync("localStorage.setItem", key, value);
}
public async ValueTask<string> GetItemAsync(string key)
{
return await JsRuntime.InvokeAsync<string>("localStorage.getItem", key);
}
public async ValueTask RemoveItemAsync(string key)
{
await JsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
}
}

59
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpAuthenticationState.cs

@ -0,0 +1,59 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.Extensions.Options;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Components.Web.Security;
public class AbpAuthenticationState : ComponentBase
{
private const string StateKey = "authentication-state-id";
[Inject]
protected ILocalStorageService LocalStorage { get; set; } = default!;
[Inject]
protected ICurrentUser CurrentUser { get; set; } = default!;
[Inject]
protected NavigationManager NavigationManager { get; set; } = default!;
[Inject]
protected IOptions<AbpAuthenticationOptions> AuthenticationOptions { get; set; } = default!;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
NavigationManager.RegisterLocationChangingHandler(OnLocationChangingAsync);
if (CurrentUser.IsAuthenticated)
{
await SetAuthenticationStateAsync();
}
else
{
await ClearAuthenticationStateAsync();
}
}
}
protected virtual async ValueTask OnLocationChangingAsync(LocationChangingContext context)
{
if (context.TargetLocation.Contains(AuthenticationOptions.Value.LogoutUrl))
{
await ClearAuthenticationStateAsync();
}
}
protected virtual async Task SetAuthenticationStateAsync()
{
await LocalStorage.SetItemAsync(StateKey, CurrentUser.GetId().ToString());
}
protected virtual async Task ClearAuthenticationStateAsync()
{
await LocalStorage.RemoveItemAsync(StateKey);
}
}

17
framework/src/Volo.Abp.AspNetCore.Components.Web/wwwroot/libs/abp/js/authentication-state-listener.js

@ -0,0 +1,17 @@
(function () {
const stateKey = 'authentication-state-id';
window.addEventListener('storage', function (event) {
if (event.key !== stateKey || event.oldValue === event.newValue) {
return;
}
if (event.oldValue || !event.newValue) {
abp.utils.removeOidcUser();
window.location.reload();
} else {
location.assign('/')
}
});
}());

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ComponentsComponentsBundleContributor.cs

@ -9,6 +9,8 @@ public class ComponentsComponentsBundleContributor : IBundleContributor
context.Add("_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js");
context.Add("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js");
context.Add("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/lang-utils.js");
context.Add("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/lang-utils.js");
context.Add("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/authentication-state-listener.js");
}
public void AddStyles(BundleContext context)

10
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Components.Server;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.AspNetCore.Components.Web.ExceptionHandling;
using Volo.Abp.AspNetCore.Components.Web.Security;
@ -49,6 +50,15 @@ public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule
context.Services
.GetHostBuilder().Logging
.AddProvider(new AbpExceptionHandlingLoggerProvider(context.Services));
if (!context.Services.ExecutePreConfiguredActions<AbpAspNetCoreComponentsWebOptions>().IsBlazorWebApp)
{
Configure<AbpAuthenticationOptions>(options =>
{
options.LoginUrl = "authentication/login";
options.LogoutUrl = "authentication/logout";
});
}
}
public override void PostConfigureServices(ServiceConfigurationContext context)

7
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ClientProxyExceptionEventHandler.cs

@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.JSInterop;
using Volo.Abp.AspNetCore.Components.Server;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Volo.Abp.Http;
@ -28,21 +29,23 @@ public class ClientProxyExceptionEventHandler : ILocalEventHandler<ClientProxyEx
using (var scope = ServiceProvider.CreateScope())
{
var options = scope.ServiceProvider.GetRequiredService<IOptions<AbpAspNetCoreComponentsWebOptions>>();
if (!options.Value.IsBlazorWebApp)
{
var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
var accessTokenProvider = scope.ServiceProvider.GetRequiredService<IAccessTokenProvider>();
var authenticationOptions = scope.ServiceProvider.GetRequiredService<IOptions<AbpAuthenticationOptions>>();
var result = await accessTokenProvider.RequestAccessToken();
if (result.Status != AccessTokenResultStatus.Success)
{
navigationManager.NavigateToLogout("authentication/logout");
navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl);
return;
}
result.TryGetToken(out var token);
if (token != null && DateTimeOffset.Now >= token.Expires.AddMinutes(-5))
{
navigationManager.NavigateToLogout("authentication/logout");
navigationManager.NavigateToLogout(authenticationOptions.Value.LogoutUrl);
}
}
else

2
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/wwwroot/global.js

@ -5,6 +5,8 @@ var abp=abp||{};(function(){abp.utils=abp.utils||{};abp.domReady=function(n){doc
var abp=abp||{};(function(){abp.utils=abp.utils||{};abp.utils.updateHTMLDirAndLangFromLocalStorage=function(){var i=JSON.parse(localStorage.getItem("Abp.IsRtl")),n=document.getElementsByTagName("html")[0],t;n&&(t=localStorage.getItem("Abp.SelectedLanguage"),t&&n.setAttribute("lang",t),i&&n.setAttribute("dir","rtl"))};abp.utils.updateHTMLDirAndLangFromLocalStorage()})();
(function(){const n="authentication-state-id";window.addEventListener("storage",function(t){t.key===n&&t.oldValue!==t.newValue&&(t.oldValue||!t.newValue?(abp.utils.removeOidcUser(),window.location.reload()):location.assign("/"))})})();
/*!
* Bootstrap v5.1.3 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)

6
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/Menus/MyProjectNameMenuContributor.cs

@ -68,13 +68,15 @@ public class MyProjectNameMenuContributor : IMenuContributor
{
var accountStringLocalizer = context.GetLocalizer<AccountResource>();
var authServerUrl = _configuration["AuthServer:Authority"] ?? "";
context.Menu.AddItem(new ApplicationMenuItem(
"Account.Manage",
accountStringLocalizer["MyAccount"],
$"Account/Manage",
$"{authServerUrl.EnsureEndsWith('/')}Account/Manage",
icon: "fa fa-cog",
order: 1000,
null).RequireAuthenticated());
target: "_blank").RequireAuthenticated());
return Task.CompletedTask;
}

24
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/wwwroot/global.js

File diff suppressed because one or more lines are too long

24
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/wwwroot/global.js

File diff suppressed because one or more lines are too long

24
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/wwwroot/global.js

File diff suppressed because one or more lines are too long

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/App.razor

@ -8,7 +8,7 @@
<base href="/" />
<!--ABP:Styles-->
<link href="global.css?_v=638473199568040519" rel="stylesheet"/>
<link href="global.css?_v=638490521600060525" rel="stylesheet"/>
<link href="main.css" rel="stylesheet"/>
<!--/ABP:Styles-->
<link href="MyCompanyName.MyProjectName.Blazor.Client.styles.css" rel="stylesheet"/>
@ -36,7 +36,7 @@
</div>
<!--ABP:Scripts-->
<script src="global.js?_v=638473199570937070"></script>
<script src="global.js?_v=638490521602018274"></script>
<!--/ABP:Scripts-->
<!-- <TEMPLATE-REMOVE IF-NOT='PWA'> -->

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/wwwroot/global.css

File diff suppressed because one or more lines are too long

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/wwwroot/global.js

@ -5,3 +5,5 @@ var abp=abp||{};(function(){abp.utils=abp.utils||{};abp.domReady=function(n){doc
var abp=abp||{};(function(){abp.utils=abp.utils||{};abp.utils.updateHTMLDirAndLangFromLocalStorage=function(){var i=JSON.parse(localStorage.getItem("Abp.IsRtl")),n=document.getElementsByTagName("html")[0],t;n&&(t=localStorage.getItem("Abp.SelectedLanguage"),t&&n.setAttribute("lang",t),i&&n.setAttribute("dir","rtl"))};abp.utils.updateHTMLDirAndLangFromLocalStorage()})();
(function(){const n="authentication-state-id";window.addEventListener("storage",function(t){t.key===n&&t.oldValue!==t.newValue&&(t.oldValue||!t.newValue?(abp.utils.removeOidcUser(),window.location.reload()):location.assign("/"))})})();

4
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host/App.razor

@ -8,7 +8,7 @@
<base href="/" />
<!--ABP:Styles-->
<link href="global.css?_v=638473199135168410" rel="stylesheet"/>
<link href="global.css?_v=638490522235034880" rel="stylesheet"/>
<link href="main.css" rel="stylesheet"/>
<!--/ABP:Styles-->
<link href="MyCompanyName.MyProjectName.Blazor.Host.Client.styles.css" rel="stylesheet"/>
@ -30,7 +30,7 @@
</div>
<!--ABP:Scripts-->
<script src="global.js?_v=638473199135794271"></script>
<script src="global.js?_v=638490522235601638"></script>
<!--/ABP:Scripts-->
</body>

Loading…
Cancel
Save