Azure SignalR Service Serverless with Frontdoor & ASP.NET negotiation

Azure Frontdoor is a great way to secure your application against the outside world. One downside though is the lack of websocket support meaning no SignalR communication can get through. This is where the SignalR Service’s serverless option comes in handy. It allows us to establish a connection with the service directly which acts as a proxy between clients and servers.

As illustrated below the client will request the SignalR credentials from the backend via a regular REST call. The Web App negotiates with the SignalR Service, retreives the credentials for the user and passes the result back to the client. With the credentials the user can directly connect to the SignalR Service via Websockets, bypassing the Azure Frontdoor.

For the negotiation we use the Microsoft.Azure.SignalR.Management NuGet package which allows us to communicate with the SignalR Service using Managed Identity.

public async Task<NegotiationResponse> Negotiate(Guid userId, CancellationToken ct)
{
string connectionString = "Endpoint=https://myapp.service.signalr.net;AuthType=azure.msi;Version=1.0;"
ServiceManager serviceManager = new ServiceManagerBuilder()
.WithOptions(option =>
{
option.ServiceEndpoints =
[
new(connectionString)
];
})
.BuildServiceManager();
ServiceHubContext hubContext = await _serviceManager
.CreateHubContextAsync(_options.HubName, ct)
.ConfigureAwait(false);
NegotiationResponse response = await _hubContext.NegotiateAsync(
new NegotiationOptions()
{
UserId = userId.ToString(),
EnableDetailedErrors = _options.EnableDetailedErrors
}, ct)
.ConfigureAwait(false);
return response;
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.