{"id":16841,"date":"2016-03-21T10:58:52","date_gmt":"2016-03-21T09:58:52","guid":{"rendered":"http:\/\/infozone.se\/?p=16841"},"modified":"2016-03-21T10:58:52","modified_gmt":"2016-03-21T09:58:52","slug":"authenticate-against-signalr","status":"publish","type":"post","link":"https:\/\/www.infozone.se\/en\/latest-news\/authenticate-against-signalr\/","title":{"rendered":"Authenticate against a ASP.NET Core 1.0 (vNext) SignalR application using JWT"},"content":{"rendered":"
If you are a ASP.NET developer, SignalR is a great library to enable real time communication between your server and client code. SignalR ships with both server and client libraries and I’ll assume that you are somewhat familiar with the two, otherwise you can read up on them here<\/a>.<\/p>\n The reason behind why I write this blog post is to tackle the difficulties of authentication towards a SignalR application using a token, in this case a JSON Web Token<\/strong>. The problem is that the SignalR JavaScript library does not provide support for passing headers in requests<\/em>, headers in which these tokens are normally sent. More specifically via the Authorization header<\/strong> and this is also where the JWT middleware will look for it.<\/p>\n I’ll walk you through how to install both SignalR and the JwtBearerAuthentication middleware as well as writing our own “querystring-to-authorization header” translation middleware. In the end we should have the means of authenticate ourselves to a SignalR endpoint by passing a token as a part of the query string instead of as a header.<\/p>\n Let’s get started by adding support for SignalR in our ASP.NET Core 1.0 application by installing (adding to our project.json file) the following NuGet packages from the aspnet master MyGet feed<\/a>.<\/p>\n Once these are installed successfully we simply add and configure SignalR in our Startup class. I’ve omitted everything else for brevity.<\/p>\n <\/p>\n This should install and configure our application to be a SignalR endpoint so lets get down to business, authentication!<\/p>\n This is great and all, but what if you want to authenticate using Json Web Tokens<\/a> (i.e. JWT)? Typically one would send a JWT in the Authorization header<\/strong> using the Bearer-<\/strong>schema and the content of the authorization header would be in the form “Bearer <token>”. This is all fine and dandy and is supported by ASP.NET Core 1.0 by downloading the following NuGet packages (at the time of writing I am using the rc1-final versions).<\/p>\n <\/p>\n<\/div>\n And configuring them by adding the authentication service and use the JwtBearerAuthentication middleware provided by the JwtBearer NuGet package.<\/p>\n Pay extra attention to the options that we need to provide when we add our JwtBearerAuthentication.<\/em> Audience is the indented recipient of the token, as explained here<\/a>. If you are using Azure AD we would specify the App ID URI of the application that requested the token as Audience. Authority is a URL to your identity provider, aka Authority. If you are using Azure AD this would typically point to your tenant (https:\/\/login.microsoftonline.com\/{tenantId}).<\/p>\n Now, one would then assume that simply sending the token in the authorization header from the client when connecting to the hub would authenticate the user and yes, that would work. However, the SignalR JavaScript client library<\/a> provided by Microsoft does not include a way to modify or add headers<\/span> sent to the server. It does however provide a way to append a query string to each request<\/a> and that is something that we want to take advantage of.<\/p>\nInstalling SignalR<\/h2>\n
\"Microsoft.AspNet.SignalR.Server\": \"3.0.0-rc1-final\"<\/pre>\n<\/div>\n
public class Startup\n{\n public void ConfigureServices(IServiceCollection services)\n {\n services.AddSignalR();\n }\n public void Configure(IApplicationBuilder app)\n {\n app.UseSignalR();\n }\n}<\/pre>\n
Authenticate against SignalR<\/h2>\n
[Authorize]\npublic class MyGreatHub : Hub\n{\n}<\/pre>\n
\"Microsoft.AspNet.Authentication\": \"1.0.0-rc1-final\",\n\"Microsoft.AspNet.Authentication.JwtBearer\": \"1.0.0-rc1-final\"<\/pre>\n
<\/pre>\n
public class Startup\n{\n public void ConfigureServices(IServiceCollection services)\n {\n services.AddAuthentication();\n services.AddSignalR();\n }\n public void Configure(IApplicationBuilder app)\n {\n app.UseJwtBearerAuthentication(options =>\n {\n options.AutomaticAuthenticate = true;\n options.AutomaticChallenge = true;\n options.Authority = \"Url to your identity provider\"; \/\/For example, a tenant url if you are using Azure AD\n options.Audience = \"Your audience\"; \/\/For example, an Azure AD AppIdUri\n });\n app.UseSignalR();\n }\n}<\/pre>\n
Pass our JWT in the query string<\/h2>\n