【问题标题】:Play 2.5 Deadbolt-2's @subjectPresentOr migrating from Java -> Scala播放从 Java -> Scala 迁移的 2.5 Deadbolt-2 的 @subjectPresentOr
【发布时间】:2017-05-01 10:53:33
【问题描述】:

我正在将现有的 Java Play 2.5 应用程序迁移到 Scala,并在视图 main.scala.html 中发现使用以下 deadbolt-2subjectPresentOr

@subjectPresentOr() {
  <ul class="nav navbar-nav navbar-right">
    @defining(userProvider.getUser(session())) { user =>
    ... user is present html
    }
} {
  ... user is NOT present html    
}

将所有控制器和操作迁移到 Scala(并从 Java -> Scala 更改 deadbolt-2 依赖项)后,由于 subjectPresentOr 需要 AuthenticatedRequest[Any] 类型的隐式请求,我收到以下编译器错误:

main.scala.html:49: could not find implicit value for parameter request: 
    be.objectify.deadbolt.scala.AuthenticatedRequest[Any]

我有一些直觉,为什么……有时,例如当用户尚未登录时,没有类型 deadbolt-2 的 AuthenticatedRequest[_] 的请求,而是超类类型 play.api.mvc.RequestHeader 并且它不能正确地与其子类 AuthenticatedRequest[_] 隐式匹配。

问题是为什么这首先在 Java 版本中有效?@subjectPresentOr 的 Java 版本不需要任何隐式请求:)

为了在 Scala 版本中修复它,我将使用模式匹配包装 @subjectPresentOr 块以发现隐式请求的动态类型,并且只有当它的动态类型是 AuthenticatedRequest[_] 时,我才会显示该块并传递给 @ 987654337@ 明确表示该类型的缩小请求。虽然这不是超级优雅,但我想不出任何其他方式......

【问题讨论】:

    标签: scala playframework deadbolt-2


    【解决方案1】:

    Java 版本的 Play 可以通过 ThreadLocals 使用 Http.Context,而 Scala 版本使用请求。这些可能是隐含的或显式的。

    查看您的控制器,当您将 Deadbolt 添加到操作时,您将收到 AuthenticatedRequest。因此,

    的非死栓动作
    def foo = Action { request =>
      // request is of type Request
    }
    

    将收到 Request 类型的 request,而相同的操作受 Deadbolt 保护

    def foo = actionBuilder.SubjectPresentAction().defaultHandler() { request =>
      // request is of type AuthenticatedRequest
    }
    

    收到AuthenticatedRequest 类型的request

    如果您想将 Request 转换为 AuthenticatedRequest,因为您正在调用包含 Deadbolt 约束但您的控制器操作不受约束的模板,您可以使用 WithAuthRequestAction

    def foo = actionBuilder.WithAuthRequestAction().defaultHandler() { request =>
      // request is of type AuthenticatedRequest
    }
    

    如果你注入 DeadboltActions 代替 ActionBuilders,同样适用:

    def foo= deadboltActions.SubjectPresent()() { request =>
      // request is of type AuthenticatedRequest
    }
    

    您也可以使用 new AuthenticatedRequest(request, None) 从现有的 Request 创建一个 AuthenticatedRequest 的实例,而不使用 Subject

    【讨论】:

    • @(Steve Chalonder) 谢谢,是的,这一切都说得通。我认为在每个返回RequestHeader 的操作中使用actionBuilder.WithAuthRequestAction().defaultHandler() 解决了这个问题。顺便说一句,这是一个较短的版本:actionBuilder.WithAuthRequestAction()()?再次感谢您的帮助和 Deadbolt-2 非常干净的代码,Play 应该从中学习,例如关于将 Java 与 Scala 分开的简洁设计,而不是令人困惑的 play.xplay.api.x
    • ActionBuildersDeadboltActions 提供了另一种语法,因此actionBuilder.WithAuthRequestAction()() 无效。请参阅deadbolt-scala.readme.io/docs/action-buildersdeadbolt-scala.readme.io/docs/action-composition 了解更多详情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多