I'm developing an ASP.NET Core MVC web application. The application uses Windows Authentication. I want to send notifications to the client side from an API controller once it receives a post request. I found this resource https://learn.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-5.0) that says I need to use a CustomUserIdProvider to get the Id of tat specific user. However, I'm not sure how should I call the following method:
_myHub.Clients.User(specificUserId).SendAsync("ReceiveMessage", message);
How can I get that specificUserId in my API controller. I tried injecting the CustomUserIdProvider and then calling this method:
_myHub.Clients.User(_customUserIdProvider.GetUserId(conn)).SendAsync("ReceiveMessage", message);
However I don't know how do I get the HubConnectionContext conn object that is required by the GetUserId method from this API controller.
This is the CustomUserIdProvider class:
public class CustomUserIdProvider : IUserIdProvider
{
public string GetUserId(HubConnectionContext connection)
{
return connection.User?.Identity?.Name;
}
}
In case this doesn't work, is there any other way in which one can send SignalR notifications to specific users authenticated with Windows Authentication to an ASP.NET MVC web application? Thanks!
You are not supposed to pass the instance of the CustomUserIdProvider to the hub. The IUserIdProvider defines what happens behind the scenes on how the SignalR returns the userId and identifies the users.
You register your CustomUserIdProvider
services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
The point of this is to match the user id you will provide to the user id it looks for in its list of users.
Then if you are trying to do this in a controller and not a hub I assume you can do:
public Controller(IHttpContextAccessor httpContextAccessor)
{
_userId = httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
}
As seen in this answer: https://stackoverflow.com/a/36641907/2490286
and then
_myHub.Clients.User(_userId).SendAsync("ReceiveMessage", message);