Over a million developers have joined DZone.

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

· Java Zone

Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code! Brought to you in partnership with ZeroTurnaround.

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.



 

The Java Zone is brought to you in partnership with ZeroTurnaround. Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code!

Topics:

Published at DZone with permission of Krishna Prasad , DZone MVB .

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}