Hubs is generally an easier API to use as compared to Persistent Connection, and that's the case for the authorization process too. With this recipe, we'll see how to provide the same behavior for a persistent connection.
We'll be writing a simple ASP.NET application first, and then we'll add the necessary authorization features to reach the same goal. For the authorization, we'll be using Windows Authentication again, and we'll configure IIS Express accordingly.
Before writing the code of this recipe, we need to create a new empty web application, which we'll call Recipe35
.
We first create an empty web application, and we'll make it functional without any authorization bits, which we'll be adding afterwards. We'll perform the following steps:
EchoConnection
that is derived from PersistentConnection
. To do that, we can navigate to Add | New Item… from the context menu of the project entry inside the Solution Explorer window, and from there look for SignalR Persistent Connection Class (v2). We'll add a simple method to broadcast back whatever data is received from the connected client. The code is as follows:using System.Threading.Tasks; using Microsoft.AspNet.SignalR; namespace Recipe35 { public class EchoConnection : PersistentConnection { protected override Task OnReceived( IRequest request, string connectionId, string data) { return Connection.Broadcast(data); } ... } }
The dots are there to mark where we'll be adding the authorization bits.
Startup
class. In this case, we are using a persistent connection; therefore, we'll have to use the corresponding mapping extension method, as shown in the following code:using Microsoft.Owin; using Owin; using Recipe35; [assembly: OwinStartup(typeof(Startup))] namespace Recipe35 { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR<EchoConnection>("/echo"); } } }
The only relevant portion is the line where MapSignalR()
is called to wire our EchoConnection
type to the /echo
endpoint.
index.html
page and adding some simple testing code to it, as follows:<script src="Scripts/jquery-2.1.0.js"></script> <script src="Scripts/jquery.signalR-2.0.2.js"></script> <script> $(function() { var c = $.connection('echo'), c.received(function(data) { console.log(data); }); c.start() .done(function () { c.send('hello'), }); }); </script>
This kind of code has already been illustrated in Chapter 5, Using a Persistent Connection, so we'll skip any further comments.
Testing this application is very simple. We browse to the index.html
page and look at the browser's console to see a hello string popping up. After verifying that it works, we can move on and add the authentication and authorization bits. For any general discussion about those topics, you can refer to the Authorizing requests on a Hub recipe. Let's proceed with the following steps:
AuthorizeRequest()
method, and from there do all the necessary checks to decide whether to accept or reject the request, as shown in the following code:protected override bool AuthorizeRequest( IRequest request) { return request.User.Identity.Name == @ "DOMAINuser" ; }
The AuthorizeRequest()
method is automatically called every time a remote request is performed, and it's supplied with a reference to the current request. The authorization step has already taken place, therefore the request
argument contains all the information necessary to apply our authorization process. The method has to return a Boolean value, which will either be true to authorize the call or false to deny access, and that's it. In our example, we simply get access to the current principal token and check whether the name of the user matches a specific one, but of course in real-world applications we would perform a more meaningful authorization process.
We are now ready to test the application again by changing the string we verify the identity against, as we did in the previous recipe. We'll observe that the hello string will be printed only if the authorization process will pass. Using breakpoints in Visual Studio, we can verify that each request is actually passing through the AuthorizeRequest()
method, and that its output is governing the actual execution of the request.
18.119.172.146