Search code examples
asp.net-mvc-3.net-4.0signalrsignalr-hubsignalr.client

SignalR .Net client fails to connect (upd: how to set auth. cookie?)


This thing is dragging me nuts.

I have a .net 4.0 console app and I have an MVC web app.

javascript clients can connect and talk to the server - no problems here...

but my .net client throws System.AggregateException with InnerException = "Unexpected character encountered while parsing value: <. Path...

so I created an empty MVC3 app, added SignalR libraries, and .net client surprisingly connects to that. But for some reason it doesn't to the other one. I've checked everything, both MVC3 apps, both use the same SignalR libs, the same NewtonsoftJson... I thought it must be something with the routing, I guess no - js client works.

var connection = new HubConnection("http://localhost:58746");
var hubProxy = connection.CreateProxy("myProxy");
connection.Start().Wait() // it fails here on Wait

What could it be?

UPD: I have figured... it's because FormsAuthentication on the server. Now is there any way to feed .ASPXAUTH cookie to SignalR so it can connect to the server?


Solution

  • Ok... stupid me... SignalR failed to connect because it cannot breach server's Forms authentication. So what needed to be done is to get the auth cookie and stick it to the HubConnection.CookieContainer...

    so I wrote this method method to login with a username and get the cookie:

    private Cookie GetAuthCookie(string user, string pass)
    {
        var http = WebRequest.Create(_baseUrl+"Users/Login") as HttpWebRequest;
        http.AllowAutoRedirect = false;
        http.Method = "POST";
        http.ContentType = "application/x-www-form-urlencoded";
        http.CookieContainer = new CookieContainer();
        var postData = "UserName=" + user + "&Password=" + pass + "&RememberMe=true&RememberMe=false&ReturnUrl=www.google.com";
        byte[] dataBytes = System.Text.Encoding.UTF8.GetBytes(postData);
        http.ContentLength = dataBytes.Length;
        using (var postStream = http.GetRequestStream())
        {
            postStream.Write(dataBytes, 0, dataBytes.Length);
        }
        var httpResponse = http.GetResponse() as HttpWebResponse;
        var cookie = httpResponse.Cookies[FormsAuthentication.FormsCookieName];
        httpResponse.Close();
        return cookie;
    }
    

    And used it like this:

    var connection = new HubConnection(_baseUrl)
                    {
                        CookieContainer = new CookieContainer()
                    };
                    connection.CookieContainer.Add(GetAuthCookie(_user, _pass));
    

    Works perfectly!