How can I access user claims in Identity 2 when using a SignalR hub with an ASP.NET MVC 5 project?

I have an application written using C # at the top of the Asp.Net MVC 5 Framework.

I use SignalR 2.2.2 to create a WebSocket connection between the browser and the server to send messages from the server to the browser.

However, I need to have access to my object ClaimsIdentityfor a registered user so that I can determine which messages are in the podcast.

Typically, I would get access to identity claims this way

IPrincipal user = System.Web.HttpContext.Current.User
IIdentity identity = user.Identity;
var claims = (IEnumerable<Claim>)identity.Claims;

However, this string System.Web.HttpContext.Currentreturns null; not letting me get a registered user.

I assume that SignalR creates a synchronous connection, so System.Web.HttpContext.Currentit is null.

I am also trying to use HubCallerContexas suggested in this SO Question , but the object is Contextalso null.

System.Web.HttpContextBase httpContext = Context.Request.GetHttpContext();

How can I correctly access user requests in my hub?

I have added the following key to my appSettingsin my Web.config since I am using Framework 4.5.1

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
+4
source share
2 answers

If you use SignalR hubs and want to authorize methods in the same hub, you need to use the Authorize attribute on the hub. those.

[Authorize]
public class MessagingHub: Hub
{
    public Task Send(string data)
    {
        return Clients.Caller.SendAsync("Send", "Data To Send");
    }
}

Hub, , Send , :

[Authorize]
public class MessagingHub: Hub
{
   public Task Send(string data)
  {
     var identity = (ClaimsIdentity)Context.User.Identity;
     //one can access all member functions or properties of identity e.g, Claims, Name, IsAuthenticated... 
      return Clients.Caller.SendAsync("Send", "Data To Send");
  }
}

Json Web Tokens (JWT) , , , Hub Send.

NB. - Angular 6.

import { HubConnection } from "@aspnet/signalr";
import * as signalR from '@aspnet/signalr';
...
private _messagingHubConnection: HubConnection | undefined;
public async: any;
...
constructor(){}
...
 SendMessg(): void {
    if (this._messagingHubConnection) {
      this._messagingHubConnection.invoke('Send');
    }
  }
...

ngOnInit(){
    this._messagingHubConnection= new signalR.HubConnectionBuilder()
      .withUrl("messaging", { accessTokenFactory: () => "jwt_token" }) //have a logic that gets the current user authentication token from the browser 
      .build();

    this._messagingHubConnection.start().then(() => {
        this.SendMessg();
      }).catch(err => console.error(err.toString()));

    if (this._messagingHubConnection) {
      this._messagingHubConnection.on('Send', (data: any) => {
        //data represents response/message received from Hub method'd return value.
      });

    }
}

NB. .Net Core 2.1, Hub. , signalR

.Net Core , StartUp.cs ;

services.AddSignalR(); // under ConfigureServices

app.UseWebSockets();
app.UseAuthentication();
app.UseSignalR(routes => {
    routes.MapHub<LoopyHub>("/messaging");
});

NB. , GitHub SignalR, , , - - . .. .

, .NET Core & Angular; , , , .

+1

.

, Hub. , . .

 [Authorize]
    public class YourHub: Microsoft.AspNetCore.SignalR.Hub
    {

          public override async Task OnConnectedAsync()
          {
             ...
             var identity = (ClaimsIdentity)Context.User.Identity;
          }
  }
0

Source: https://habr.com/ru/post/1689422/


All Articles