-
Notifications
You must be signed in to change notification settings - Fork 85
Hooking into the HTTP negotiation
It is possible to hook into the HTTP negotiation with the delegate provided in the server configuration and check/add cookies or return a custom HTTP status code.
The only thing you need is to provide a handler of this type in the configuration:
void OnHttpNegotiationDelegate(WebSocketHttpRequest request, WebSocketHttpResponse response)
The handler will be executed as part of the HTTP negotiation process. Keep in mind that the HTTP negotiations happen in parallel, so if you introduce a mutual exclusion element (like a lock
) in the handler, you will probably reduce the connection rate.
Please note that cookies are not sent when using an IP address as connection target.
new WebSocketListenerOptions()
{
PingTimeout = TimeSpan.FromSeconds(10),
SubProtocols = new[] { "text" },
OnHttpNegotiation = (request, response)=>
{
if(request.Cookies["ConnectionId"] == null)
response.Cookies.Add(new Cookie("ConnectionId", Guid.NewGuid().ToString()));
}
}
You may retrieve that ConnectionId
by for example doing:
Guid connectionId = Guid.Empty;
Cookie cookie = ws.HttpRequest.Cookies["ConnectionId"] ?? ws.HttpResponse.Cookies["ConnectionId"];
if (cookie == null || !Guid.TryParse(cookie.Value, out connectionId))
throw new WebSocketException("The connection has not identifier");
new WebSocketListenerOptions()
{
PingTimeout = TimeSpan.FromSeconds(10),
SubProtocols = new[] { "text" },
OnHttpNegotiation = (request, response)=>
{
var authCookie = request.Cookies[".ASPXAUTH"];
if(authCookie == null || !IsAuthCookieValid(authCookie.Value))
response.Status = HttpStatusCode.Unauthorized;
}
}
Remember you need to share the "machineKey" between your web site and your websocket server if you want to be able of reading the authentication cookie content.