簡體   English   中英

基於Play(Scala)中的JSON令牌授權的自定義操作組合

[英]Custom Action composition to authorize based on JSON token in Play (Scala)

與大多數有關Action組成的討論(例如討論)不同,我需要在Action中解析傳入的JSON請求。 這是因為我們的應用程序提供了嵌入在JSON中的安全令牌(通常不包含在標頭中)。

我想要實現的是:

object AuthenticatedAction extends ActionBuilder[UserRequest] with ActionTransformer[Request, UserRequest] {
    // Do something magical here that will:
    // 1. parse the inbound request.body.validate[GPToken]
    // 2. (do stuff with the token to check authorization)
    // 3. if NOT authorized return an HTTP NOTAUTHORIZED or FORBIDDEN
    // 4. otherwise, forward the request to the desired endpoint
}

object SomeController extends Controller
    val action = AuthenticatedAction(parse.json) { implicit request =>
        request.body.validate[SomeRequest] match {
            // Do whatever... totally transparent and already authorized
        }
    }
    ...

入站JSON將始終具有令牌,例如:

{
    "token":"af75e4ad7564cfde",
    // other parameters we don't care about
}

因此,我正在考慮僅希望我們解析(而不是解析復雜的,深層嵌套的JSON結構),我可能只有一個GPToken對象:

class GPToken(token: String)
object GPToken { implicit val readsToken = Json.reads[GPToken] }

然后,在AuthenticationAction的“魔術”中,我可以反序列化令牌,對數據庫執行檢查授權的工作,然后將請求傳遞或發回NOTAUTHORIZED。 但這就是我迷路的地方...我該如何獲取json正文,對其進行解析並通過我的安全層過濾所有傳入的請求?

我認為將令牌移至您的請求標頭會更好。 這樣做將允許您使用Play的AuthententicatedBuilder,它是一個ActionBuilder來幫助進行身份驗證。

如果可以這樣做,那么您可能會具有如下特征:

trait Authentication {
  object Authenticated extends play.api.mvc.Security.AuthenticatedBuilder(checkGPToken(_), onUnauthorized(_))

  def checkGPToken(request: RequestHeader): Option[User] = {
    request.headers.get("GPToken") flatMap { token =>
      // Do the check with the token
      // Return something about the user that will be available inside your actions
    }
  }

  def onUnauthorized(request: RequestHeader) = {
    // Do something when it doesn't pass authorization
    Results.Unauthorized
  }
}

現在,使用控制器,您可以輕松地創建需要身份驗證的操作。

object SomeController extends Controller with Authentication {
    def someAction = Authenticated { req =>
      // Your user your header check is available
      val user = req.user
      // Do something in the context of being authenticated
      Ok
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM