Thursday, February 28, 2013

Using Deadbolt for Authorization in Your Play 2 Site With Scala

I needed security in my site. I needed a feature that would guarantee for only authorized users to go into some of the controllers (links) of my site. For non-registered users, I wanted to display a "non authorized" page so they could either login or register. I also needed for Play 2.1 using Scala 2.10. My search lead me to deadbolt 2 (D2). In this post I will cover the following:

  • How to include deadbolt into your Play site
  • Create a security service to validate registered users
  • Send non-registered users to a "not authorized" page
  • Add security to your controller
  • How to validate registered users from the template

Include deadbolt into your Play site

The first thing that you need is to include the deadbolt plugin into your site. You need to include it inside your project/Build.scala. Here you will find that I added the play-plugin-mailer already, postgresql, and finally deadbolt. I had to include the resolvers for the application to work.

Add Security Service to Your Application

Before you implement the service, you need to create a subject. Subject is what determines a user in deadbolt. It also handles privileges such as roles and permissions. Below is the code for a User inside the app/models package:

Now, that we have a subject, we need to implement the DeadboltHandler to validate registered users/subjects and to send the non-register users to a "non-register" page. The main application that takes care of user validation is the getSubject.

Here the code tries to get the the username from the HTTP session, and in case there is a user, return a subject (User) with that session name. Otherwise, return a "None". When returning None, Deadbolt automatically knows that this is not a valid/registered user.

Send Non-Registerd users to a "Non-Registered" Page

For those users that are not registered (None Subject), the "onAuthFailure" will take effect.

Below is the code inside the app/security package.

Add Security to the Controller

Now, that the DeadboltHandler is implemented, you have to make some decisions based on the business rules of your site. For example, if you have an Contact Directory page where only registered users could see it, you need to assure that there is a Subject (registered user) present.

Noticed that I am also passing a new MyDeadboltHandler to the page. This is because I also need to implement some business rules inside the template. In this site, I needed to show a "Login" link for those non-registered users or display a "Contact Directory" and a "Logout" link for those authenticated users. Below is my navigation template.

Inside the "subjectNotPresent" we will handle the case when the user is not logged in. Whereas, in the subjectPresent we will show the Logout and the Contact Directory link pages.

For those controllers that doesn't require the a subject to be present, I still had to pass the implemented deadbolt handler because it had to be in every one of my pages. This is to validate if the user is authenticated.

3 comments:

  1. Thank you, Marcelo - that's very useful quick reference for Deadbolt 2 essentials.

    But regarding getSubject implementation - why it was needed to repeat username extraction and decomposition? username(request) is called twice, and second time as username(request).get, all though you have Some[String] already decomposed by pattern matching.

    ReplyDelete