Code-Sharp/WampSharp

HTTP/1.1 101 Switching Protocols when throwing WampAuthenticationException or UnauthorizedAccessException from GetSessionAuthenticator method

Closed this issue · 7 comments

Hi,

I am trying to validate the request header "origin" value when authenticating the request for establishing WAMP connection in GetSessionAuthenticator method by implementing IWampSessionAuthenticatorFactory interface. If request origin header value is not valid(as per my validation rules) then I am throwing WampAuthenticationException or UnauthorizedAccessException from GetSessionAuthenticator method. However, the switching of protocols from HTTP to WebSocket is still happening which is not expected. PFA for the sample request and response. Please confirm if its expected to have the protocol switch event if authentication fails.

WAMP_SwitchingProtocols_Issue

darkl commented

Hi Elad,

Thanks for the quick reply. Could you please share sample code for filtering out illegal origins and throw exception?
I am using WAMPSharp.dll version="20.1.1"

darkl commented

Thank you.. I am using a MVC application as client and a C# windows service as WAMP server. My requirement is if any request that comes to my WAMP server then filtering out of the origin should happen on the WAMP server end itself. The sample reference link that you shared talks about middleware between client and server. I am trying to implement on the server side filtering.

My sample code is below. Please suggest if the below approach is fine or if any other better way.
public IWampSessionAuthenticator GetSessionAuthenticator(WampPendingClientDetails details, IWampSessionAuthenticator transportAuthenticator)
{
HelloDetails helloDetails = details.HelloDetails;
string transprtDetailsSerialized = JsonConvert.SerializeObject(details.HelloDetails.TransportDetails);
ConnectionTransportDetails transportDetails = JsonConvert.DeserializeObject(transprtDetailsSerialized);
var originHeader = transportDetails.http_headers.Where(h => string.Equals(h.Key, "origin", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
if (originHeader.Key != null)
{
Uri originURI = new Uri(originHeader.Value);
string host = originURI.Host;
if (!allowedHeaders.Contains(host))
{
throw new UnauthorizedAccessException("Illegal origin");
}
}
}

darkl commented

Thank you Elad.. Mine is windows service. Could you please suggest on how to do in windows service?

darkl commented

My comments have nothing to do with whether you run your code in a Console Application/Windows Service/IIS/Windows Form/etc.

This functionality seems to be built-in in ASP.NET Core. See here. Recall that a WampHost registration for ASP.NET Core looks like this

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        WampHost host = new WampHost();

        app.Map("/ws", builder =>
        {
            builder.UseWebSockets();

            host.RegisterTransport(new AspNetCoreWebSocketTransport(builder),
                                   new JTokenJsonBinding(),
                                   new JTokenMsgpackBinding());
        });

        host.Open();
    }

You should call UseWebSockets with your desired allowed origins:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        WampHost host = new WampHost();

        var webSocketOptions = new WebSocketOptions();
        webSocketOptions.AllowedOrigins.Add("https://client.com");
        webSocketOptions.AllowedOrigins.Add("https://www.client.com");

        app.Map("/ws", builder =>
        {
            builder.UseWebSockets(webSocketOptions);

            host.RegisterTransport(new AspNetCoreWebSocketTransport(builder),
                                   new JTokenJsonBinding(),
                                   new JTokenMsgpackBinding());
        });

        host.Open();
    }

Elad