在Blazor服务端应用程序中,当使用Cookie Authentication时,直接访问受保护的页面链接时,即使用户未经过身份验证,仍会成功访问页面。 为解决此问题,可以在页面加载时进行身份验证。 在具有身份验证要求的组件中实现IAsyncDisposable接口,并在DisposeAsync()方法中取消订阅身份验证事件。
下面是示例代码:
@page "/protected"
@inject AuthenticationStateProvider AuthenticationStateProvider
@if(ViewModel.IsAuthenticated)
{
You have access to the protected content!
}
else
{
You don't have permission to access the protected content.
}
@code {
private AuthenticationState AuthenticationState =>
AuthenticationStateProvider.GetAuthenticationStateAsync().Result;
private protectedViewModel ViewModel;
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
ViewModel = new protectedViewModel(authState.User);
}
protected override async ValueTask DisposeAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
ViewModel.Dispose(authState.User);
await base.DisposeAsync();
}
public class protectedViewModel : IAsyncDisposable
{
private readonly IDisposable _subscription;
public protectedViewModel(ClaimsPrincipal user)
{
_subscription = user.Identity.IsAuthenticated
? null
: NavigationManager.NavigateToTaskAsync("/login", true).ContinueWith(t => (IDisposable)null).Result;
}
public bool IsAuthenticated => _subscription == null;
public async ValueTask DisposeAsync()
{
if (_subscription is not null)
{
await ((NavigationManager)services.GetRequiredService()).NavigateToAsync("/login", true);
_subscription.Dispose();
}
}
}
}