SignalR Core 中的用户 ID

Art*_*yom 8 asp.net-core asp.net-core-signalr

我将 SignalR 与 ASP.NET Core 2.0 结合使用,并尝试向特定用户发送通知,如下所示:

_notification.Clients.User(id).InvokeAsync("SendMes");
Run Code Online (Sandbox Code Playgroud)

其中 _notification 是 IHubContext。但这不起作用。当我向所有用户发送通知时,一切都很好,所有用户都会收到通知。但是当我将其发送给特定用户时,什么也没有发生。在连接中我需要用户,但似乎他没有用户ID。那么我该怎么做呢?通过访问身份和声明?如果是这样,该怎么做?

Fra*_*ein 8

我遇到了类似的问题,以下文章帮助我解决了这个问题:https://learn.microsoft.com/en-us/aspnet/core/signalr/groups ?view=aspnetcore-2.1

在集线器(服务器端)中,我检查了 Context.UserIdentifier,它为空,即使用户已通过身份验证。事实证明,SignalR 依赖于 ClaimTypes.NameIdentifier,而我只是设置 ClaimTypes.Name。所以,基本上我添加了另一个声明并且它成功了(之后 Context.UserIdentifier 设置正确)。

下面,我分享我拥有的部分身份验证代码,以防有帮助:

var claims = userRoles.Split(',', ';').Select(p => new Claim(ClaimTypes.Role, p.Trim())).ToList();
claims.Insert(0, new Claim(ClaimTypes.Name, userName));
claims.Insert(1, new Claim(ClaimTypes.NameIdentifier, userName)); // this is the claim type that is used by SignalR
var userIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);
Run Code Online (Sandbox Code Playgroud)

请注意,SignalR 用户和组区分大小写。


Chr*_*att 0

用户 ID 提供程序默认使用IPrincipal.Identity.Name,对于大多数身份部署来说,最终都是电子邮件地址。在较旧的 SignalR 中,可以使用您自己的提供商进行自定义。

您只需实现以下接口:

public interface IUserIdProvider
{
    string GetUserId(IRequest request);
}
Run Code Online (Sandbox Code Playgroud)

然后通过以下方式附加它:

GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new MyIdProvider());
Run Code Online (Sandbox Code Playgroud)

我不确定核心版本中有多少变化。IUserIdProvider仍然存在,尽管界面略有变化:

public interface IUserIdProvider
{
    string GetUserId(HubConnectionContext connection);
}
Run Code Online (Sandbox Code Playgroud)

当您调用 时AddSignalRConfigureServices它会设置以下内容,当然还有其他内容:

services.AddSingleton(typeof(IUserIdProvider), typeof(DefaultUserIdProvider));
Run Code Online (Sandbox Code Playgroud)

DefaultUserIdProvider显然是默认实现。似乎没有任何配置选项可以覆盖它,因此如果您需要使用自己的提供程序,则必须替换服务描述符:

services.Replace(ServiceDescriptor.Singleton(typeof(IUserIdProvider), 
                                             typeof(MyCustomUserIdProvider)));
Run Code Online (Sandbox Code Playgroud)

显然,这需要在调用AddSignalR. 另外,请注意,在配置 SignalR 之前,必须先配置 auth。否则,用户将无法使用集线器。