Course contentsShow
← C#
Lesson 1462 of 1,90813. Real-time Communication with SignalRFree lesson

Customizing Connection Handshake Logic

Implement custom validation logic during the initial connection upgrade process.

In this lesson, you will learn how to intercept and validate the initial SignalR handshake before a client is permitted to fully join your hub.

The Handshake Interception Point

When a client initiates a connection, SignalR performs a "negotiation" request. While you have previously learned about standard authorization policies, sometimes you need to enforce custom application logic—such as verifying a custom header, validating an API key from a query string, or checking an external allowlist—at the very moment the WebSocket upgrade is requested.

We achieve this by hooking into the OnConnectedAsync method within your Hub class. Although this executes after the connection is established, it acts as our primary guard for the session. If validation fails, we can throw an exception, which immediately closes the connection before any business logic methods are invoked.

Implementing Custom Validation

Consider a scenario where you want to restrict connections based on a custom X-Device-Id header. Since standard HttpContext is available within the Hub context, you can inspect the request during the connection lifecycle:

public class ChatHub : Hub
{
    public override async Task OnConnectedAsync()
    {
        var httpContext = Context.GetHttpContext();
        var deviceId = httpContext?.Request.Headers["X-Device-Id"].FirstOrDefault();

        if (string.IsNullOrEmpty(deviceId) || !IsValidDevice(deviceId))
        {
            // Throwing an exception here aborts the connection 
            // and notifies the client of the failure.
            throw new HubException("Connection rejected: Invalid Device ID.");
        }

        await base.OnConnectedAsync();
    }
}

Why Logic Placement Matters

By placing this logic in OnConnectedAsync, you ensure that the server resource allocation for the Hub lifecycle is terminated early if the client does not meet your specific custom criteria. If you try to perform this validation inside a standard Hub method, the client would have already successfully established a session, potentially consuming memory and threading resources unnecessarily. Always aim to terminate invalid connections as early as possible in the handshake phase to keep your pipeline clean and performant.

Key Takeaway: Use the OnConnectedAsync override to inspect the HttpContext and enforce custom handshake requirements, throwing a HubException to immediately reject connections that fail your business-specific criteria.