【问题标题】:oauth2 implementation in the Play scala web-socketPlay scala web-socket 中的 oauth2 实现
【发布时间】:2015-10-16 12:06:49
【问题描述】:

我已经使用 Play2.3 scala 开发了 web-socket,我正在尝试使用 oauth-provider 在 Play scala web-socket 中实现 oauth2。

web-socket的代码sn-p:

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的代码sn-p:

我已将“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?

有人知道,如何为上述 web-socket 实现 oauth2?

更新:

我尝试实现 oauth 和 web socket:

代码 sn-p:

  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]

【问题讨论】:

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


    【解决方案1】:

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

    我建议您使用 tryAcceptWithActor 而不是 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) _)
          }
        }
      }
    }
    

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

    【讨论】:

    • 感谢您的回复。当我添加这一行时,我得到“方法映射的参数不足:(隐式执行器:scala.concurrent.ExecutionContext)scala.concurrent.Future[Product with Serializable with scala.util.Either[play.api.mvc.Result ,akka.actor.ActorRef => akka.actor.Props]]。未指定值参数执行器。"错误。
    • 您能否检查以下问题。请帮助我进一步进行。谢谢。 stackoverflow.com/q/37183156/1584121
    • 如果你有时间,请看看这个问题。谢谢! - stackoverflow.com/q/37183156/1584121
    • 我现在才注意到您的评论。我从未使用过 Slick,但我认为您只是在选择查询中使用了 Slick 的 Join 功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    相关资源
    最近更新 更多