2016-05-27 65 views

回答

0

我在这里勾勒出一个粗略的办法,但我会把它发展为立足于发挥剪影种子主激活模板时,我得到一次完整的工作示例。需要

两个主要步骤。

首先,你com.mohiva.play.silhouette.api.Identity实现还需要实现be.objectify.deadbolt.scala.models.Subject

其次,从com.mohiva.play.silhouette.api.RequestHandlerBuilder借用一些代码,并将其集成到您的DeadboltHandler实现。

import javax.inject.Inject 

import be.objectify.deadbolt.scala.models.Subject 
import be.objectify.deadbolt.scala.{ AuthenticatedRequest, DeadboltHandler, DynamicResourceHandler } 
import com.mohiva.play.silhouette.api.{ LoginInfo, RequestProvider, Silhouette } 
import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator 
import models.User 
import play.api.mvc.Results._ 
import play.api.mvc.{ Request, Result } 
import utils.auth.DefaultEnv 

import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.Future 

class MyDeadboltHandler @Inject() (silhouette: Silhouette[DefaultEnv]) extends DeadboltHandler { 
    override def beforeAuthCheck[A](request: Request[A]): Future[Option[Result]] = Future.successful(None) 

    override def getSubject[A](request: AuthenticatedRequest[A]): Future[Option[Subject]] = 
    if (request.subject.isDefined) { 
     Future.successful(request.subject) 
    } else { 
     // this else branch is taken from com.mohiva.play.silhouette.api.RequestHandlerBuilder 
     silhouette.env.authenticatorService.retrieve(request).flatMap { 
     // A valid authenticator was found so we retrieve also the identity 
     case Some(a) if a.isValid => 
      silhouette.env.identityService.retrieve(a.loginInfo).map(i => i) 
     // An invalid authenticator was found so we needn't retrieve the identity 
     case Some(a) if !a.isValid => Future.successful(None) 
     // No authenticator was found so we try to authenticate with a request provider 
     case None => handleRequestProviderAuthentication(request).flatMap { 
      // Authentication was successful, so we retrieve the identity and create a new authenticator for it 
      case Some(loginInfo) => silhouette.env.identityService.retrieve(loginInfo).flatMap { (i: Option[User]) => 
      silhouette.env.authenticatorService.create(loginInfo)(request).map((a: CookieAuthenticator) => i) 
      } 
      // No identity and no authenticator was found 
      case None => Future.successful(None) 
     } 
     } 
    } 

    // this whole function is taken from com.mohiva.play.silhouette.api.RequestHandlerBuilder 
    private def handleRequestProviderAuthentication[B](implicit request: Request[B]): Future[Option[LoginInfo]] = { 
    def auth(providers: Seq[RequestProvider]): Future[Option[LoginInfo]] = { 
     providers match { 
     case Nil => Future.successful(None) 
     case h :: t => h.authenticate(request).flatMap { 
      case Some(i) => Future.successful(Some(i)) 
      case None => if (t.isEmpty) Future.successful(None) else auth(t) 
     } 
     } 
    } 

    auth(silhouette.env.requestProviders) 
    } 

    override def onAuthFailure[A](request: AuthenticatedRequest[A]): Future[Result] = 
    Future.successful(request.subject.map(subject => Redirect(controllers.routes.ApplicationController.index())) 
     .getOrElse(Redirect(controllers.routes.SignInController.view()))) 

    override def getDynamicResourceHandler[A](request: Request[A]): Future[Option[DynamicResourceHandler]] = Future.successful(None) 
} 

在您的控制器中,您现在可以使用Deadbolt约束条件而不是Silhouette授权。例如...

class ApplicationController @Inject() (
    val messagesApi: MessagesApi, 
    silhouette: Silhouette[DefaultEnv]) 
    extends Controller with I18nSupport { 

    def index = silhouette.SecuredAction.async { implicit request => 
    Future.successful(Ok(views.html.home(request.identity))) 
    } 
} 

可以

class ApplicationController @Inject() (
    val messagesApi: MessagesApi, 
    deadbolt: ActionBuilders) 
    extends Controller with I18nSupport { 

    def index = deadbolt.SubjectPresentAction().defaultHandler() { implicit request => 
    Future.successful(Ok(views.html.home(request.subject))) 
    } 
} 
被替换