6

我希望能够在经过身份验证的请求上使用 BodyParser,如果我的身份验证设置为 ZenTasks 示例,我无法弄清楚如何做到这一点。

我的认证方法,

def IsAuthenticated(f: => String => Request[AnyContent] => Result) = {
  Security.Authenticated(username, onUnauthorized) { user =>
    Action(request => f(user)(request))
  }
}

def HasRole(role: List[String])
  (f: => String => Request[AnyContent] => Result) = IsAuthenticated {
  user => request => if (role.contains(getRole(user))) {
    f(user)(request) // This function returns the result.
  } else {
    Results.Forbidden
  }
}

我的控制器方法,

def controller = HasRole(List("admin")) { user => _ => { 
  Action(parse.temporaryFile){ implicit request =>
    request.body.moveTo(new File("/tmp/filepath"))
    Redirect(routes.home)
  }
}

这是我看到的错误,

[error]  found   : play.api.mvc.Action[play.api.libs.Files.TemporaryFile]
[error]  required: play.api.mvc.Result
[error]       Action(parse.temporaryFile){ implicit request =>
[error]                                  ^

这是一个相关的问题:parse.json of authenticated play request

这个人找到了一种解决方法,我相信临时文件示例也有一个,但我想知道我正在做什么(或为什么)不起作用。

4

1 回答 1

6

我相信我已经弄清楚了,主要是因为我在原始问题中遗漏了一些我没有意识到重要的细节。

问题是我包装了一个,Action { Action { } }因为该IsAuthenticated方法已经调用了其中的Action函数。我最终做的是IsAuthenticated用一个BodyParser作为参数的方法重载函数。因为我使用的TemporaryFile方法不是 的子类AnyContent,所以我还必须更改请求类型。

现在,这就是我的Secured特质:

def IsAuthenticated(f: => String => Request[Any] => Result) = {
  Security.Authenticated(username, onUnauthorized) { user =>
    Action(request => f(user)(request))
  }
}

def IsAuthenticated(b: BodyParser[Any] = parse.anyContent)
  (f: => String => Request[Any] => Result) = {
  Security.Authenticated(username, onUnauthorized) { user =>
    Action(b)(request => f(user)(request))
  }
}

def HasRole(role: List[String])(b: BodyParser[Any] = parse.anyContent)
  (f: => String => Request[Any] => Result) = IsAuthenticated(b) {
  user => request => getRole(user) match {
    case Some(r) if role.contains(r) => f(user)(request)
    case _ => Results.Forbidden
  }
}

这就是我的控制器的样子:

def controller = HasRole(List("admin"))(parse.temporaryFile) { user => request =>
  request.body match {
    case b:TemporaryFile => b.moveTo(new File("/tmp/file"))
    case _ => Status(404)
  }
}

希望这对其他人有帮助!

于 2012-06-20T13:41:32.910 回答