39
votes

I can see that there is an option in HubConnection to pass parameters through url request from client. Is there any way to pass specific token through http headers from JS or .NET clients?

6

6 Answers

58
votes

There is no easy way to set HTTP headers for SignalR requests using the JS or .NET client, but you can add parameters to the query string that will be sent as part of each SignalR request:

JS Client

$.connection.hub.qs = { "token" : tokenValue };
$.connection.hub.start().done(function() { /* ... */ });

.NET Client

var connection = new HubConnection("http://foo/",
                                   new Dictionary<string, string>
                                   {
                                       { "token", tokenValue }
                                   });

Inside a Hub you can access the community name through the Context:

Context.QueryString["token"]

You can add to the query string when making persistent connections as well.

EDIT: It is now possible to set headers on the .NET SignalR client as pointed out by some of the commenters.

Setting Headers on the .NET Client

var connection = new HubConnection("http://foo/");
connection.Headers.Add("token", tokenValue);
17
votes

You can add headers on either Connection or HubConnection using the .NET client (as @abnanda mentions):

var connection = new Connection("http://signalr/");
connection.Headers.Add("custom-header", "value");

On the server side you can retrieve the header value from IRequest in e.g. OnConnected:

var header = request.Headers["custom-header"];

However, I have not yet found a way to do this with the JS client (there is no headers or addHeaders on the $connection object).

I have posted a question on that at: http://forums.asp.net/t/1910020.aspx/1?Add+custom+HTTP+header+on+client+side+connect+call+SignalR+1+1+1+

EDIT: The headers are not exposed since the websocket client (in browser) does not support it (so it would not be possible to implement it across transports). See David Fowlers response in the post above.

4
votes

I solved this by adding my information to the querystring, which is available on the IConnected.Connect() method.

On the .NET client you pass the querystring into your HubConnection:

var connection = new HubConnection("http://localhost:8080/", "myInfo=12345");

On the JS client you set the qs property before starting the connection:

$.connection.hub.qs = "myInfo=12345";

You can then access this information on the server in the Connect() method:

var myInfo = Context.QueryString["myInfo"];
Groups.Add(Context.ConnectionId, myInfo);
3
votes

With the js client, I don't think the header is supported but it must go via the querysting instead.

For the javascript client that is not the generated js proxy, you can add extra information to the querystring like this:

var connection = $.hubConnection("http://localhost:3306/signalr");
connection.qs = "somekey=somevalue";
var hubProxy = connection.createHubProxy('hubname');

Messages such as ping, negotiate, abort, connect will now include this querystring value.

It's possible to send the header if you affect the ajax global setup. I have observed it making to the server but have not tested that it makes it in every case you might need.

  $.ajaxSetup({
      beforeSend: function (xhr)
      {
         xhr.setRequestHeader("Authorization","Token token=\"abcdef\"");        
      }
  });
3
votes

Hello guys this is the best approach for a .Net Client!

In my client added the Authorization header to the HubConnectionBuilder like this:

For Bearer Token ->

HubConnection = new HubConnectionBuilder()
            .WithUrl($"https://10.0.2.2:5001/chatHub", (opts) =>
            {                    
                opts.Headers.Add("Authorization", new AuthenticationHeaderValue(
                        "Bearer", "YOUR_TOKEN").ToString());                    
            })                
            .Build();

You can also use Basic token like this ->

HubConnection = new HubConnectionBuilder()
            .WithUrl($"https://10.0.2.2:5001/chatHub", (opts) =>
            {                    
                opts.Headers.Add("Authorization", new AuthenticationHeaderValue(
                        "Basic", Convert.ToBase64String(
                            Encoding.Default.GetBytes(
                                "Username" + ":" + "Password"
                                ))).ToString());                    
            })                
            .Build();
1
votes
using Microsoft.AspNet.SignalR.Client;

HubConnection = new HubConnection(_url);
HubProxy = HubConnection.CreateHubProxy(_hubname);
HubConnection.Headers.Add("Authorization", "Bearer "+authToken);
HubConnection .Start().Wait();