Play scala web-socket 中的 oauth2 实现
oauth2 implementation in the Play scala web-socket
我已经使用 Play2.3 scala 开发了网络套接字,我正在尝试使用 oauth-provider.
在 Play scala 网络套接字中实现 oauth2
网络套接字的代码片段:
object LoginWS {
def props(out: ActorRef) = Props(new LoginWS(out))
}
class LoginWS(out: ActorRef) extends Actor {
def receive = {
case json_req: JsObject =>
val login_status : String = "Success"
out ! Json.toJson(JsObject(Seq("login_status" -> JsString(login_status))))
}
}
object WebSocketController extends Controller {
def login = WebSocket.acceptWithActor[JsValue, JsValue] { request =>
out =>
LoginWS.props(out)
}
}
用于 REST 服务的 oauth2 代码片段:
我已将“scala-oauth2-provider-slick”示例用于 oauth2 实施。
trait MyOAuth extends OAuth2Provider {
override val tokenEndpoint: TokenEndpoint = MyTokenEndpoint
}
object OAuth2Controller extends Controller with MyOAuth {
val cats = TableQuery[CatsTable]
implicit val catFormat = Json.format[Cat]
def accessToken = Action.async { implicit request =>
issueAccessToken(new Oauth2DataHandler())
}
def list = Action.async { implicit request =>
authorize(new Oauth2DataHandler()) { authInfo =>
DBAction { implicit rs =>
Ok(toJson(cats.list))
}.apply(request)
}
}
}
如何在上面的 web-socket 代码中实现 oauth2?
有人知道,如何为上述网络套接字实现 oauth2?
更新:
我尝试实现 oauth 和 web 套接字:
代码片段:
def login = WebSocket.tryAcceptWithActor[JsValue, JsValue] { request =>
authorize(new Oauth2DataHandler()) { authInfo =>
val user = authInfo.user // User is defined on your system
println(user.toString())
}
}
遇到以下问题:
1) polymorphic expression cannot be instantiated to expected type; found : [A]scala.concurrent.Future[play.api.mvc.Result] required: Either[play.api.mvc.Result,play.api.mvc.WebSocket.HandlerProps] (which expands to) Either[play.api.mvc.Result,akka.actor.ActorRef ⇒ akka.actor.Props]
2) type mismatch; found : Unit required: scala.concurrent.Future[play.api.mvc.Result]
OAuth2Provider提供了protectedResource实例,所以你可以在你的WebSocket控制器中直接调用handleRequest方法进行授权。
客户端通过 HTTP header 或查询参数发送访问令牌。
我推荐你使用 tryAcceptWithActor 而不是 acceptWithActor。
因为如果用户发送无效的访问令牌,你需要 return 错误的请求。
object LoginWS {
def props(user: User)(out: ActorRef) = Props(new LoginWS(user, out))
}
object WebSocketController extends Controller extends MyOAuth {
def login = WebSocket.tryAcceptWithActor[JsValue, JsValue] { request =>
Future.successful {
(protectedResource.handleRequest(request, new Oauth2DataHandler())).map {
case Left(e) => e match {
case e: OAuthError if e.statusCode == 400 => Left(BadRequest.withHeaders(responseOAuthErrorHeader(e)))
case e: OAuthError if e.statusCode == 401 => Left(Unauthorized.withHeaders(responseOAuthErrorHeader(e)))
}
case Right(authInfo) => Right(LoginWS.props(authInfo.user) _)
}
}
}
}
我不确定这段代码是否可以编译。
但是我已经使用这个库编写了类似的代码。
我已经使用 Play2.3 scala 开发了网络套接字,我正在尝试使用 oauth-provider.
在 Play scala 网络套接字中实现 oauth2网络套接字的代码片段:
object LoginWS {
def props(out: ActorRef) = Props(new LoginWS(out))
}
class LoginWS(out: ActorRef) extends Actor {
def receive = {
case json_req: JsObject =>
val login_status : String = "Success"
out ! Json.toJson(JsObject(Seq("login_status" -> JsString(login_status))))
}
}
object WebSocketController extends Controller {
def login = WebSocket.acceptWithActor[JsValue, JsValue] { request =>
out =>
LoginWS.props(out)
}
}
用于 REST 服务的 oauth2 代码片段:
我已将“scala-oauth2-provider-slick”示例用于 oauth2 实施。
trait MyOAuth extends OAuth2Provider {
override val tokenEndpoint: TokenEndpoint = MyTokenEndpoint
}
object OAuth2Controller extends Controller with MyOAuth {
val cats = TableQuery[CatsTable]
implicit val catFormat = Json.format[Cat]
def accessToken = Action.async { implicit request =>
issueAccessToken(new Oauth2DataHandler())
}
def list = Action.async { implicit request =>
authorize(new Oauth2DataHandler()) { authInfo =>
DBAction { implicit rs =>
Ok(toJson(cats.list))
}.apply(request)
}
}
}
如何在上面的 web-socket 代码中实现 oauth2?
有人知道,如何为上述网络套接字实现 oauth2?
更新:
我尝试实现 oauth 和 web 套接字:
代码片段:
def login = WebSocket.tryAcceptWithActor[JsValue, JsValue] { request =>
authorize(new Oauth2DataHandler()) { authInfo =>
val user = authInfo.user // User is defined on your system
println(user.toString())
}
}
遇到以下问题:
1) polymorphic expression cannot be instantiated to expected type; found : [A]scala.concurrent.Future[play.api.mvc.Result] required: Either[play.api.mvc.Result,play.api.mvc.WebSocket.HandlerProps] (which expands to) Either[play.api.mvc.Result,akka.actor.ActorRef ⇒ akka.actor.Props]
2) type mismatch; found : Unit required: scala.concurrent.Future[play.api.mvc.Result]
OAuth2Provider提供了protectedResource实例,所以你可以在你的WebSocket控制器中直接调用handleRequest方法进行授权。 客户端通过 HTTP header 或查询参数发送访问令牌。
我推荐你使用 tryAcceptWithActor 而不是 acceptWithActor。 因为如果用户发送无效的访问令牌,你需要 return 错误的请求。
object LoginWS {
def props(user: User)(out: ActorRef) = Props(new LoginWS(user, out))
}
object WebSocketController extends Controller extends MyOAuth {
def login = WebSocket.tryAcceptWithActor[JsValue, JsValue] { request =>
Future.successful {
(protectedResource.handleRequest(request, new Oauth2DataHandler())).map {
case Left(e) => e match {
case e: OAuthError if e.statusCode == 400 => Left(BadRequest.withHeaders(responseOAuthErrorHeader(e)))
case e: OAuthError if e.statusCode == 401 => Left(Unauthorized.withHeaders(responseOAuthErrorHeader(e)))
}
case Right(authInfo) => Right(LoginWS.props(authInfo.user) _)
}
}
}
}
我不确定这段代码是否可以编译。 但是我已经使用这个库编写了类似的代码。