Play scala Web-socket中的oauth2实现

时间:2015-10-16 12:06:49

标签: scala playframework websocket oauth-2.0 playframework-2.3

我使用Play2.3 scala开发了Web套接字,我正在尝试使用oauth-provider在Play scala Web套接字中实现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)
    }
  }
}

如何在上面的网络套接字代码中实现oauth2?

任何人都知道,如何为上面的web-socket实现oauth2?

更新:

我尝试实现oauth和web socket:

代码段:

  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]

1 个答案:

答案 0 :(得分:1)

OAuth2Provider提供protectedResource实例,因此您可以直接调用handleRequest方法在WebSocket控制器中进行授权。 客户端通过HTTP标头或查询参数发送访问令牌。

我建议你使用tryAcceptWithActor intead acceptWithActor。 因为如果用户发送了无效的访问令牌,您需要返回错误的请求。

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) _)
      }
    }
  }
}

我不确定这段代码是否可以编译。 但我使用这个库编写了类似的代码。