I’ve blogged quite a bit about ColdFusion 10 WebSockets, but one topic I haven’t touched on yet is authentication. I want to be clear that authentication is one part of a “security process” (does that sound overly dramatic?) in terms of your entire application. I’ve already blogged about how you need to lock down your WebSocket broadcasts and what you can to secure messages. This post then will focus on just the authentication aspect. You have two main options to build in authentication with your ColdFusion WebSocket applications.
The second option, called “Single Sign On”, simply means that you can connect your WebSocket code to an existing login. However - this doesn’t work with any old session-based login system. You must be using the ColdFusion “cflogin” feature.
This blog post will focus on the first of these - onWSAuthenticate.
I’ve got two divs. This was my simple way of having two states in the application. The first one, called stepone, is loaded on startup and contains a login form. (Note that it also allows you to select subchannels, but that’s not relevant to this blog entry.)
As I’ve described before, the message handler for WebSockets end up getting everything. This means you must write code in there to handle multiple situations. In my code you will support the subscribe event, the response to authentication, and general chat. Note specifically the code handling authentication results. If it failed (code == -1), we alert the user and give them a hint. If it succeeded, we subscribe them.
Now lets switch to the server-side, specifically, my Application.cfc.
Most of the code here is boilerplate, but pay attention to the new onWSAuthenticate. In order to log a user in, you must edit one particular key of the connectionInfo structure: authenticated. Note that - like other WebSocket calls, we can also place ad hoc data in the structure. My logic puts “starwars” in for all users and an admin key for one particular user. To be clear - that part is totally optional and is just there as a demonstration. The critical part is setting authenticated to true.
Ok… are we done yet? Nope. There is one super critical aspect to this setup that is not quite covered in the docs. If I go into my console and try to send a message, I’ll be able to. Why? Because the message handler doesn’t check for authentication. We need to lock down both the allowSubscribe event and the allowPublish. You may be wondering - why do I have to worry about allowPublish? You can actually publish an event without subscribing. Subscribing simply means, “I want to hear what you have to say”, whereas publishing is you shouting into the channel (so to speak). Let’s now look at my handler.
As I mentioned above, the two important methods here are allowSubscribe and allowPublish. In each we check the relevant structure and respond accordingly. Previously I thought allowSubscribe was all I needed, but, like all good script kiddies, I did some testing in allowPublish and discovered that this was a hole in my understanding.