SignalR Core not sending cookies

1.3k views Asked by At

Cookies are the BIGGEST frustration I have with web development, they have plagued me for many years. I would just like to say that "I hate Cookies"... and CORS. (Note I understand that they are important security features there to protect us.)

I am developing a Blazor WebAssembly app, I sign the user in with Cookie authentication at a controller and I can see that that cookie is being sent on all subsequent requests.
But the cookie is not being sent on the connection request to the SignalR Hub.

My goal is to group all connections to the Hub by a claim that should be present when the user logs in.
But of course I cannot go any further because I cannot see any claims.

This is my TeamHub on the server:

[Authorize]
public class TeamHub : Hub
{
    public async override Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();

        var key = Context.User.Claims.FirstOrDefault(c => c.Type == IdentityUserClaims.ClientKey)?.Type;
        if (!string.IsNullOrWhiteSpace(key))
        {
            await Clients.Groups(key).SendAsync("memberConnected", new ConnectedMemberResult()
            {
                Id = Context.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value,
                FirstName = Context.User.Claims.FirstOrDefault(c => c.Type == IdentityUserClaims.FirstName)?.Value,
                LastName = Context.User.Claims.FirstOrDefault(c => c.Type == IdentityUserClaims.LastName)?.Value,
                OnlineStatus = OnlineStatus.Online
            });
            await Groups.AddToGroupAsync(Context.ConnectionId, key);
        }
    }

Here is my code for connection to the hub:
There are some delegates here to allow me to configure the request, but I don't know what to put in here to set cookies on every request:

hubConnection = new HubConnectionBuilder()
    .WithUrl($"{Global.Api}teamhub", configure =>
    {
        configure.WebSocketConfiguration = opt =>
        {

        };
    })
    .Build();

Not Authenticated and no Cookies

1

There are 1 answers

0
Luke T O'Brien On

... I almost had the answer.
In order to get Cookies working with Blazor I had to create a MessageHandler:

public class CredentialsDelegatingHandler : DelegatingHandler
{
    public CredentialsDelegatingHandler()
    {
        InnerHandler = new HttpClientHandler();
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request = request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
        return await base.SendAsync(request, cancellationToken);
    }
}
...
services.AddSingleton(new HttpClient(new CredentialsDelegatingHandler())
{
    BaseAddress = new Uri(Builder.HostEnvironment.BaseAddress)                
});

I just needed to use that same handler here:

hubConnection = new HubConnectionBuilder()
    .WithUrl($"{Global.Api}teamhub", configure =>
    {
        configure.HttpMessageHandlerFactory = message =>
        {
            return new CredentialsDelegatingHandler();
        };
    })
    .Build();