“类型不匹配”实现类型化Security.authenticated

时间:2016-03-23 10:23:42

标签: scala playframework

我正在尝试为非String版本的Security.authenticated实现一个通用的身份验证特性。如果身份验证成功,我希望返回Person的实例,而不是默认的String(例如用户名)。到目前为止代码是这样的:

trait Secured {
  def withPerson[Person](f: => Person => Request[AnyContent] => Result) = {

    def findPerson(request:RequestHeader) : Option[Person] =
      Person.findByRuid("me")
    def noPerson(request:RequestHeader) = Results.BadRequest("No access")

    Security.Authenticated[Person](findPerson, noPerson) { person =>
      Action { implicit request => 
        f(person)(request)
      }
    }
  }
}

Person.findByRuid在模型包中定义为返回Option[Person],所以我认为这很简单,但我遇到某种类型的参数/类型路径问题,并接收以下编译 - 调用我的模型方法的行上的时间错误消息:

type mismatch; 
  found : Option[models.Person] 
  required: Option[Person]

我似乎错过了Scala类型教育中的某些内容,并希望得到帮助。如何将我的models.Person与Person类型参数相关联?

1 个答案:

答案 0 :(得分:1)

要解决您的问题,请远程使用withPerson

中的type参数
def withPerson(f: => Person => Request[AnyContent] => Result) 

正如您所看到的那样,没有必要,已经定义了Person。

如果您想定义一般的安全特性,您可以执行类似

的操作
trait Secured[A] {

  def validate(request:RequestHeader) : Option[A]

  def secure(f: => A => Request[AnyContent] => Result) = {

    def notAllowed(request:RequestHeader) = Results.BadRequest("No access")

    Security.Authenticated[A](validate, notAllowed) { a =>
      Action { implicit request =>
        f(a)(request)
      }
    }
  }
}

trait SecuredWithPerson extends Secured[Person] {
  def validate(request:RequestHeader) : Option[Person] =
    Person.findByRuid("me")
}