I want to add chat real-time feature to my Web project. I'm using asp.net SignalR 2.4 to implement that feature. But i struggle to get UserId from bearer token in hub class.
I provide token from client side using angular 7 and i can get that token via query string in hub class.
I can easily get UserId in one of my controller using:
var userId = User.Claims.First(c => c.Type == "UserID").Value;
But in hub class User is always null Code from my hub class:
public override Task OnConnectedAsync()
{
var identity = (ClaimsIdentity)Context.User.Identity;
var connectionId = Context.ConnectionId;
var query = Context.GetHttpContext().Request.Query;
var token = query["access_token"].ToString();
return base.OnConnectedAsync();
}
Code from client-side using angular 7:
ngOnInit(): void {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:50792/chat',{
accessTokenFactory: () => {
return this.token;
},
} as signalR.IHttpConnectionOptions)
.build();
// this.hubConnection.Headers.Add("Authorization", "Bearer " +
this.token);
this.hubConnection
.start()
.then(() => console.log('Connection started'))
}
You have to hook the OnMessageReceived
event in order to allow the JWT authentication handler to read the access token from the query string.
builder.Services.AddAuthentication(options =>
{
// ...
}).AddJwtBearer(options =>
{
// ...
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/chat"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
From Microsoft documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With