I'm looking for some good resources, patterns and practices on how to handle basic security needs, such as authorization, in client side JavaScript.
I'm building a website with a back-end system running one of the common MVC frameworks. The back-end will handle all of the real security needs: authorization and authentication. The front is going to be built with Backbone.js, jQuery and a few other libraries to facilitate a very rich user experience.
Here's an example of one scenario I need to handle:
I have a grid of data with a few buttons on top of it. If you select an item in the grid, certain buttons become enabled so you can take that action on the selected item. This functionality is easy to build...
Now I need to consider authorization. The back-end server will only render the buttons that the user is allowed to work with. Additionally, the back-end server will check authorization when the user tries to take that action. ... so the back end is covered and the user won't be able to do what they try, if they are not authorized.
But what about the JavaScript? If my code is set up with a bunch of jQuery click handlers or other events that enable and disable buttons, how do I handle the buttons not being there? Do I just write a bunch of ugly if
statements checking for the existence of the button? Or do I write the JavaScript in a way that lets me only send the JavaScript for the buttons that exist, down to the browser, based on authorization? or ???
Now imagine a tree view that may or may not allow drag & drop functionality, based on authorization... and an add/edit form that may or may not exist based on authorization... and all those other complicated authorization needs, with a lot of JavaScript to run those pieces of the front end.
I'm looking for resources, patterns and practices to handle these kinds of scenarios, where the back end handles the real authorization but the front end also needs to account for things not being there based on the authorization.
What Are Authorization Patterns? These are security mechanisms that you can use to decide your client's privileges related to system resources. These system resources could be files, services, data, and application features built on your client's identity. One such is OAuth2.
The Backend For Frontend (a.k.a BFF) pattern for authentication emerged to mitigate any risk that may occur from negotiating and handling access tokens from public clients running in a browser.
Authentication and authorization are two vital information security processes that administrators use to protect systems and information. Authentication verifies the identity of a user or service, and authorization determines their access rights.
There are three fairly straightforward things I could see:
Modular Backbone Views I grew very fond of nested and highly modular Backbone views. That is, every row in your tree could be a Backbone view and reacting to their own authorization requirements.
Multiple Event Hashes Set up multiple event hashes on the view that you switch out with delegateEvents() based on your authorization requirements and triggered by an event. That way you get around a set of ugly if statements.
Multiple Templates In a similar vein, you specify multiple templates to render based on the authorization requirements.
All three would require an event structure that's setup (for example using your own vent
PubSub handler) where you trigger authorization checks based on the response of a RESTful server request, or based on some client-side function.
The way I handle authentication on the client is to have a singleton Backbone model that holds an isAuthenticated value that I initially populate from the server with:
@{
App.user.set({ isAuthenticated: @UserSession.IsAuthenticated.ToString().ToLower() });
}
Then all javascript controls/functionality that change behavior based on Authentication basically just listen to changes on this field and re-renders themselves into the correct state. All this view/logic is done with JavaScript so it works at page generation time (by the server) or on the client with Javascript/ajax.
I don't maintain event handlers to existing/hidden functionality, I re-create all the UI elements and re-hook up all the event handlers after the views are re-rendered based on the isAuthenticated flag.
The nice thing is that once you login with ajax on the client (i.e. after the server page has been rendered) you just need to set the same field and as if by magic (Backbone FTW :) it all works and renders correctly.
Anything on the client side can be hacked. So what we're doing in our singlepage js app is entitlements on the server. We combine a list of entitlements per user and have an OAuth token that we pass to the client and is sent back with each request. then in the server side before an action is taken we see if the user is authenticated for this action.
Of course, this doesn't protect you from someone at a cafe with firesheep...but thats another problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With