Blazor 自定义身份验证状态提供程序

Blazor Custom Authentication State Provider

我创建了一个自定义身份验证状态提供程序,用于检查我们内部 LDAP 服务的用户名和密码。 我的以下代码在初始登录期间工作正常。但是登录后,如果我按 F5 或刷新页面,它会自动转到登录页面。 有人可以帮忙吗?

public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
    private readonly ILdapAuthenticationService _ldapAuthenticationService;
    private ClaimsPrincipal _cachedClaimsPrincipal;

    public CustomAuthenticationStateProvider(ILdapAuthenticationService 
ldapAuthenticationService)
    {
        _ldapAuthenticationService = ldapAuthenticationService;
    }

    public override async 
Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState>
        GetAuthenticationStateAsync()
    {
        if (_cachedClaimsPrincipal != null)
            return await Task.FromResult(
                new 
Microsoft.AspNetCore.Components.Authorization.AuthenticationState(_cachedClaimsPrincipal));

        return await Task.FromResult(new 
Microsoft.AspNetCore.Components.Authorization.AuthenticationState(new ClaimsPrincipal(new 
ClaimsIdentity())));
    }


    public void ValidateLogin(string username, string password)
    {
        if (string.IsNullOrEmpty(username)) throw new Exception("Enter username");
        if (string.IsNullOrEmpty(password)) throw new Exception("Enter password");

        if (_ldapAuthenticationService.AuthenticateUser(username, password))
        {
            _cachedClaimsPrincipal = _ldapAuthenticationService.CurrentUser.ClaimsPrincipal;
        }
        
        NotifyAuthenticationStateChanged(
            Task.FromResult(new 
 AuthenticationState(_ldapAuthenticationService.CurrentUser.ClaimsPrincipal)));
    }
}

public class RedirectToLogin : ComponentBase
{
    [Inject]
    protected NavigationManager NavigationManager { get; set; }

    [CascadingParameter]
    private Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState> 
authenticationStateTask { get; set; }

    protected override void OnInitialized()
    {
        NavigationManager.NavigateTo("/");
    }
}

已创建 RedirectToLogin,以便用户在浏览任何页面之前必须进行身份验证

您的 CustomAuthenticationStateProvider 将有一个在请求后消失的范围,因此在这个 class 的本地成员中缓存 ClaimsPrincipal 将不起作用:

private ClaimsPrincipal _cachedClaimsPrincipal;

在构造函数上添加一个调试日志,您会看到它是为每个请求创建的(因此 _cachedClaimsPrincipal 中的任何存储值都会丢失)。

public CustomAuthenticationStateProvider(ILdapAuthenticationService 
    ldapAuthenticationService)
{
    System.Diagnostics.Debug.WriteLine("Constructor");
    _ldapAuthenticationService = ldapAuthenticationService;
}

您需要将其缓存在持久位置(例如服务器端的会话对象或客户端的本地存储)。