繁体   English   中英

Blazor 服务器 Signalr 集线器缺少用户声明

[英]Blazor Server Signalr hub is missing user claims

我已经花了一个多月的时间解决这个问题无济于事。

目标是在 Blazor 服务器应用程序的 Signalr 中心获取用户声明。 我已经在我的 Github 上上传了一个非常简单的应用程序。客户端可以通过单击一个按钮来调用集线器上的一个方法,集线器方法发回一条带有 User.Identity.Name 的消息。 但是,由于用户声称是 null,所以我无法获取名称。

这是存储库: https://github.com/aadurham/blazorserverauth

很多人在这里和其他地方问同样的问题。 信息/建议/解决方案分散。 事实证明,我(可能对于我编程级别的任何人)都不可能将这些部分组合在一起并使它们工作。

我怀疑优秀的程序员不会花太多时间将各个部分放在上面的简单应用程序中。 我相信很多人,包括我自己,都会从中受益。 我希望一些好心人能伸出援手。 在这种情况下,请提出拉取请求。 我会将代码保留在那里供其他人使用,并会在以后尝试添加手册。 我也会回来尝试用一个类似简单的 Blazor WASM 应用程序做同样的事情。

提前谢谢了

从这个回购https://github.com/BrianLParker/SignalRAuth

    protected override async Task OnInitializedAsync()
    {

        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"), options =>
            {
                options.AccessTokenProvider = async () =>
                {
                    var accessTokenResult = await AccessTokenProvider.RequestAccessToken();
                    accessTokenResult.TryGetToken(out var accessToken);
                    return accessToken.Value;
                };
            })
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

[Authorize]
public class ChatHub : Hub
{
    private readonly UserManager<ApplicationUser> userManager;

    public ChatHub(UserManager<ApplicationUser> userManager)
    {
        this.userManager = userManager;
    }

    public async Task SendMessage(string user, string message)
    {
        var userId = Context.UserIdentifier;
        var applicationUser = await userManager.FindByIdAsync(userId);

        await Clients.All.SendAsync("ReceiveMessage", applicationUser.Email, message);
    }
}

我想出了一个简单的解决方案,虽然不完美但很好。 我的目标是将一些用户信息传递到集线器,以便我可以使用 userid(或任何喜欢的用户信息)注册 connectionid。 迄今为止我未能实施的可用解决方案建议在连接时添加令牌。 相反,我将用户信息添加到 header 并将其提取到集线器上,如下所示:

这是客户端代码:

@code{
    [CascadingParameter]
    private Task<AuthenticationState> _authstate { get; set; }


    private HubConnection connection;
    private AuthenticationState authstate { get; set; }
    private List<string> messages = new List<string>();



    protected override async Task OnInitializedAsync()
    {
        authstate = await _authstate;

        if (authstate != null)
        {
            var userid = authstate.User.Identity.Name;

            connection = new HubConnectionBuilder()
                .WithUrl(NavigationManager.ToAbsoluteUri("/myhub"), options => {
                    options.Headers.Add("USERID", userid);
                })
                .WithAutomaticReconnect()
                .Build();



            connection.On<string, string>("ReceiveMessage", ReceiveMessage);

            await connection.StartAsync();
        }
    }


    public void ReceiveMessage(string user, string msg)
    {
        messages.Add(user + " " + msg);
        StateHasChanged();
    }

    public async void InvokeSomething()
    {
        await connection.InvokeAsync("InvokeSomething");
    }
}

这是我在集线器上提取用户信息的方式:

public async Task InvokeSomething()
{
    var httpCtx = Context.GetHttpContext();
    var name = httpCtx.Request.Headers["USERID"].ToString();
    await Clients.All.SendAsync("ReceiveMessage", name, " invoked this");
}`

有用。 在 OnConnectedAsync 中也使用相同的方法。

希望这对某人有帮助。 github 存储库中的更新代码。

集线器上的授权属性使应用程序崩溃。 所以我认为与集线器的连接没有经过身份验证(微软文档声称我们不需要做任何其他事情)。 我希望比我有更好技能的人提供更好的解决方案。 与此同时,这似乎正在完成这项工作。

更新

找到的解决方案为了启用集线器 class 的授权,必须将用户经过身份验证时创建的安全 cookie 传递给 Blazor 服务器 SPA 应用程序。 您应该在创建集线器连接时传递 cookie。 这将允许您通过上下文 object 在 Hub 中访问所有声明,例如 UserIdentofier 和 UserName。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM