Blazor - 将用户名级联到所有组件

Nic*_*ick 0 authorization blazor

我正在编写一个 Blazor 服务器端应用程序,并在项目中启用了 Windows 身份验证。

我无法使用基于角色/策略的身份验证(我无权更改用户角色/策略),而是从 SQL 数据库中获取一组用户名来检查当前用户的哪些部分他们可以访问导航菜单。

我正在努力让所有组件都可以使用 Windows 用户名,并且可以从 @code 部分进行访问。

我在 App.razor 中看到他们使用 CascadingAuthenticationState 组件和 AuthoriseView 组件

我知道您可以使用 @context.User.Identity.Name 来显示用户名,但我不确定如何从 @code 部分中访问 @context 来获取用户名。

我也尝试过此代码并在成功显示用户名的应用程序中:

[CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    private string _authMessage;

    private async Task LogUsername()
    {
        var authState = await authenticationStateTask;
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            _authMessage = $"{user.Identity.Name} is authenticated.";
        }
        else
        {
            _authMessage = "The user is NOT authenticated.";
        }
    }
Run Code Online (Sandbox Code Playgroud)

但我不喜欢在每个组件中重复类似异步代码的想法。

我的简单想法是创建一个“AuthorizationService”类并将其注册为单例。当页面首次加载时,这将从 SQL 中获取用户名集和当前用户,并且检查逻辑可以存在于其中。

我将它注入到每个组件中,对于 NavMenu,我可以使用 if 语句来确定谁可以访问使它们可见或不可见的内容。

如果有人可以阐明如何以这种方式获取 Windows 用户名(或者更好的方式,如果存在,因为我刚刚学习并且对 Blazor 完全陌生),那就太棒了!

非常感谢

缺口

Luc*_*umb 5

为了将用户名级联到所有组件,您需要创建一个类来获取用户名,如下所示:

public class UserInfo
    {
        private readonly AuthenticationStateProvider authenticationStateProvider;

        public UserInfo(AuthenticationStateProvider authenticationStateProvider)
        {
            this.authenticationStateProvider = authenticationStateProvider;
        }

        public async Task<string> GetUserName()
        {
            var authState = await authenticationStateProvider.GetAuthenticationStateAsync();
            var user = authState.User;
            return user?.Identity?.Name ?? "Pitza man";
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在你需要在启动中注册这个类

services.AddScoped<UserInfo>();
Run Code Online (Sandbox Code Playgroud)

然后在你的主布局中你可以添加一个级联值

@inherits LayoutComponentBase
@inject UserInfo _user

<CascadingValue Value="_user.GetUserName()" Name="UserName">
    @Body
</CascadingValue> 
Run Code Online (Sandbox Code Playgroud)

然后在你的组件中可以获得这个值:

@code {
    [CascadingParameter(Name = "UserName")] public string UserName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)