如何使用多个打开的浏览器选项卡从Blazor服务器应用程序注销



我正在使用Identity开发Blazor服务器应用程序,我对安全性有些怀疑。

在用户打开多个浏览器选项卡,然后在其中一个选项卡中注销的情况下,所有其他选项卡仍然视为用户授权。该应用程序可以一直使用到下一页刷新。

正如我从AuthenticationStateProvider的文档中了解到的那样,它只在当前电路中工作,在另一个选项卡中看不到用户注销

是否有方法通知其他选项卡用户已注销?

经过一番挖掘,发现基本模板有一个几乎完整的解决方案。

Identity文件夹中有一个名为RevalidatingIdentityAuthenticationStateProvider的类。它以检查身份SecurityStamp是否被修改并更新AuthenticationState的方式扩展RevalidatingServerAuthenticationStateProvider

该模板的问题是SecurityStamp永远不会被修改——它是在用户登录时创建的,不会更改。

1.注销时更新安全戳

要更新身份验证状态,应该在用户在任何选项卡中注销时更新安全戳。这在Logout.cshtml中完成。

@page
@using Microsoft.AspNetCore.Identity
@attribute [IgnoreAntiforgeryToken]
@inject  SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@functions{
public async Task<IActionResult> OnGet()
{
if(SignInManager.IsSignedIn(User))
{
await SignInManager.SignOutAsync();
//add this to update security stamp
var identity = await UserManager.FindByEmailAsync(User.Identity.Name);
await UserManager.UpdateSecurityStampAsync(identity);
}
return Redirect("~/");
}
}

2.再验证间隔

RevalidatingIdentityAuthenticationStateProvider包含属性

protected override TimeSpan RevalidationInterval => TimeSpan.FromSeconds(30);

此属性定义两次身份验证状态检查之间的间隔。

此属性的问题在于,默认情况下,它设置为30分钟。在我看来,为了有用,间隔应该短得多。

3.在其他选项卡上注销

  • 封装在AuthorizeView组件中的组件将在重新验证触发后自动切换到NotAuthorized

  • 如果应用程序包含需要有关授权状态信息的代码,则可以这样检查:

    [CascadingParameter]
    public Task<AuthenticationState> AuthenticationStateTask { get; set; }
    protected override async Task OnInitializedAsync()
    {
    var authState = await AuthenticationStateTask;
    var user = authState.User;
    if (user.Identity.IsAuthenticated)
    {
    // do something for authenticated users
    }
    else{
    // do something when the user is not authenticated 
    }
    }
    

潜在问题

  • 上述解决方案使用基于计时器的身份验证状态轮询。根据用户数量和间隔长度的不同,这可能会导致性能问题
  • 通过电路通知认证状态提供者的解决方案将是";"更好">

当前结果

  • 测试再验证间隔设置为30秒
  • 当单个用户在多个选项卡中打开一个应用程序,然后从其中一个选项卡中的应用程序注销时,该用户将在最长30秒内自动从所有其他选项卡中的该应用程序注销

这看起来不错,但它仍然缺乏对大量用户的性能测试。

最新更新