Enterprise Integration Zone is brought to you in partnership with:

Enterprise Architect in HCL Technologies a $7Billion IT services organization. My role is to work as a Technology Partner for large enterprise customers providing them low cost opensource solutions around Java, Spring and vFabric stack. I am also working on various projects involving, Cloud base solution, Mobile application and Business Analytics around Spring and vFabric space. Over 23 yrs, I have build repository of technologies and tools I liked and used extensively in my day to day work. In this blog, I am putting all these best practices and tools so that it will help the people who visit my website. Krishna is a DZone MVB and is not an employee of DZone and has posted 64 posts at DZone. You can read more from them at their website. View Full User Profile

Incorporating Login/ Authentication into Play 2.x (Scala) application

04.10.2013
| 5003 views |
  • submit to reddit

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I will demonstrate how to extend Security.Authenticated standard Play API to implement basic authentication in your application.

I took this code play-test-security as my basis for implementing Security.Authenticated based authentication.

As a first step, I will extend this class to implement a Security trait as below,

trait Secured {
  self: Controller =>
 
  /**
   * Retrieve the connected user id.
   */
  def username(request: RequestHeader) = request.session.get("email")
 
  /**
   * Redirect to login if the use in not authorized.
   */
  def onUnauthorized(request: RequestHeader): Result
 
  def IsAuthenticated(f: => String => Request[AnyContent] => Result) =
    Security.Authenticated(username, onUnauthorized) { user =>
      Action(request => f(user)(request))
    }
}

As provided in the comment section it is clear what each method does. Next step is to plumb the login steps refer Application.scala as below,

lazy val loginForm = Form(
  tuple(
    "email" -> text,
    "password" -> text) verifying ("Invalid user or password", result => result match {
      case (email, password) => {
        println("user=" + email + " password=" + password);
        val userList = Users.authenticate(email, password)
        userList == 1
      }
      case _ => false
    }))
 
def login = Action { implicit request =>
  Ok(html.login(loginForm))
}
 
/**
 * Handle login form submission.
 */
def authenticate = Action { implicit request =>
  loginForm.bindFromRequest.fold(
    formWithErrors => BadRequest(html.login(formWithErrors)),
    user => Redirect(routes.CoffeesController.index).withSession("email" -> user._1))
}
 
/**
 * Logout and clean the session.
 */
def logout = Action {
  Redirect(routes.Application.login).withNewSession.flashing(
    "success" -> "You've been logged out")
}

The User Slick domain object and the authenticate method in User.scala looks as below,

object Users extends Table[User]("USER") {
  lazy val database = Database.forDataSource(DB.getDataSource())
 
  // -- Parsers
 
  def email = column[String]("EMAIL", O.PrimaryKey)
  def name = column[String]("NAME")
  def password = column[String]("PASSWORD")
 
  def * = email ~ name ~ password <> (User.apply _, User.unapply _)
//....
  def authenticate(email: String, password: String): Int = {
    database withSession { implicit session =>
      val q1 = for (u       println("^^^^^^^^" + Query(q1.length).first)
      Query(q1.length).first
    }
  }

Finally the CoffeesController.scala where we need to override onUnauthorized method and put the IsAuthenticated block in each action as below,

def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Application.login())
 
/**
 * Display the paginated list.
 *
 * @param page Current page number (starts from 0)
 * @param orderBy Column to be sorted
 * @param filter Filter applied on entity names
 */
def list(page: Int, orderBy: Int, filter: String = "%") = IsAuthenticated { username =>
  implicit request =>
    database withSession {
      Ok(html.coffees.list(
        Page(Coffees.list(page, pageSize, orderBy, filter).list,
          page,
          offset = pageSize * page,
          Coffees.findAll(filter).list.size),
        orderBy,
        filter))
    }
}

To test if authentication worked, start play,

play run

And when you type the url http://localhost:9000/coffee, you get the login page as below,

Scala Secured.Authenticated-login

Scala Secured.Authenticated-login

I hope this blog helped you. In my next blog, I will show how you do authorization.



 

Published at DZone with permission of Krishna Prasad, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)