Playframework2的Security使用

利用 play.api.mvc.Security的机制,实现一个trait,用于扩展controller的用户认证机制。


该trait需要实现的方法包括:

1. username定义了一个Function1的对象,用于实现从Session中取得登录成功用户的名称,或者是用户ID,根据实际情况进行修改;主要用于Security.Authenticated方法调用是的第一个参数:

   * @tparam A the type of the user info value (e.g. `String` if user info consists only in a user name)
   * @param userinfo function used to retrieve the user info from the request header
   * @param onUnauthorized function used to generate alternative result if the user is not authenticated
   * @param action the action to wrap

def Authenticated[A](
    userinfo: RequestHeader => Option[A],
    onUnauthorized: RequestHeader => Result)(action: A => EssentialAction): EssentialAction

如果该函数返回的Option对象未定义,将会触发onUnauthorized方法。实现方式,如

def username(request: RequestHeader) = request.session.get("email")


2. 主要负责在未找到用户登录认证的情况下,将页面跳转到登录页面;

def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Application.login)

3. Controller中Action的包装器,注意传入参数的类型定义,是一个层层传递的参数的过程函数,首先是String类型的用户登录凭证(存储于Session当中);其次,是Action常规使用的RequestHeader,最后是返回的Action的Result类型;

def isAuthenticated(f: => String => Request[AnyContent] => Result) = {
<span style="white-space:pre">	</span>Authenticated(username, onUnauthorized) { user =>
<span style="white-space:pre">		</span>Action(request => f(user)(request))
<span style="white-space:pre">	</span>}
    }


通过以上的思路,实现一个trait(特质)的时候,可以将其mixin到Controller中,并用isAuthenticated来包装原有的Action.

trait实现样例:

trait Secured {
  def userid(request: RequestHeader) = request.session.get(Security.username)

  def onUnautherized(request: RequestHeader) = {
    Results.Redirect(routes.Application.index).flashing(Application.FlashErrorKey -> Messages("session.error"))
  }

  def withAuth(f: => String => Request[AnyContent] => Result) = {
    Security.Authenticated(userid, onUnautherized) { user =>
      Action(request => f(user)(request))
    }
  }

  def withUser(f: UserData => Request[AnyContent] => Result) = withAuth {
    userid =>
      implicit request =>
        val user = UserBiz.getUser(userid)
        f(user)(request)
  }
}

可以将其放在Application控制器相同的文件当中。


控制器的写法变为:

object Application extends Controller with Secured

原有每个Action的实现,将使用withAuth(前面介绍的isAuthenticated方法,只是在实际实现的时候,换了个名字)进行替换:

def listUser = withAuth {
userid =>
implicit request =>
业务代码
}


通过这样的方式在当前的业务代码中,可以直接使用当前登录用户的凭证,userid。


另外,在trait实现的过程中,增加了一个扩展,withUser。它使用withAuth进行包装,在其中实现通过用户登录凭证,从后台获取的完整的用户信息。那么Action的包装就变为:

def listUser = withUser {
user =>
implicit request =>
业务代码
}
这样就可以在业务代码中直接通过user访问到完整的登录用户信息。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值