1

誰でも Deadbolt2 を Silhouette/SecureSocial と統合できたのでしょうか?

Silhouette Authorization は少し基本的で、Deadbolt2 はすべての要件を満たしていると思います。

ありがとう

4

1 に答える 1

0

ここでは大まかなアプローチをスケッチしましたが、時間があるときに play-silhouette-seed-master アクティベーター テンプレートに基づいて完全に機能する例に発展させます。

2 つの主な手順が必要です。

まず、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)
}

コントローラーで、Silhouette 承認の代わりに Deadbolt 制約を使用できるようになりました。例えば...

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)))
  }
}
于 2016-08-09T11:58:23.040 に答える