Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

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

DZone's Guide to

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

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

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.



 

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}