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

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.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s