【问题标题】:Deadbolt2 -> SecureSocial/Silhouette IntegrationDeadbolt2 -> SecureSocial/Silhouette 集成
【发布时间】:2016-09-25 13:13:10
【问题描述】:

有人设法将 Deadbolt2 与 Silhouette/SecureSocial 集成?

我觉得 Silhouette Authorization 有点基础,Deadbolt2 满足所有要求。

谢谢

【问题讨论】:

    标签: scala playframework securesocial silhouette deadbolt-2


    【解决方案1】:

    我在这里勾勒出一个粗略的方法,但我会在有时间时将其演变为基于 play-silhouette-seed-master 激活器模板的完整工作示例。

    需要两个主要步骤。

    首先,您的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)))
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-11-05
      • 2013-04-28
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多