Vertx SockJs Eventbus身份验证

时间:2017-06-06 09:59:45

标签: websocket vert.x sockjs event-bus

我试图从前端到vertx后端建立sock.js连接。

我最初的尝试看起来像这样:

let token = '<the token>';
let data = {'Authorization' : 'Bearer ' + token};
let eb = new EventBus("http://localhost:8080/eventbus");
  eb.onopen = function () {
  eb.registerHandler('notifications', data, (err, msg) =>  {
    // handle the response
  });
}

这不起作用,因为我需要在EventBus创建时发送auth数据,即使官方的sock.js文档声明这不受支持。显然现在发送new EventBus("http://localhost:9090/eventbus", data)也不起作用。

https://github.com/sockjs/sockjs-node#authorisation

我的后端处理程序:

final BridgeOptions bridgeOptions = new BridgeOptions()
  .addOutboundPermitted(new PermittedOptions().setAddress("notifications"))

final SockJSHandler sockJSHandler = SockJSHandler.create(vertx).bridge(bridgeOptions, event -> {
  event.complete(true);
});

router.route("/eventbus/*").handler(ctx -> {
  String token = ctx.request().getHeader("Authorization"); // null
});
router.route("/eventbus/*").handler(sockJSHandler);

无论我尝试了什么,标题字段Authroization始终为空。

验证sock.js连接并注册到vertx中的eventbus请求的标准方法是什么?

3 个答案:

答案 0 :(得分:4)

SockJS默认使用WebSockets。您无法使用JavaScript WebSocket API添加自定义标头(授权等)。请阅读此thread以获取更多说明。

我看到了两种方法,如何添加授权:

  1. 只需将'disabled' => false, 'uploadURL' => "https://mywebsite.com/img/upload/", 'uploadDir' => "/home/XXXXXXX/public_html/img/upload/", 'theme' => "default", 参数添加到网址:

    token

    以下是如何在服务器上获取它:

    let eb = new EventBus("http://localhost:8080/eventbus?token=" + token);
    
  2. 连接到服务器后发送授权消息。它可以是一些JSON对象,其中包含String token = ctx.request().getParam("token"); 字段。

  3. 我认为,第一种选择就足够了,但是,就事件总线和SockJS而言,第二种选择可能更难实现。

答案 1 :(得分:1)

由于无法发送Authorization标头,因此可以附加令牌查询参数(如@berserkk所述)。

但是,在某些情况下,可能不希望以纯文本形式将主登录令牌作为查询参数发送,因为它比使用标头更不透明,并且最终会被记录在哪里。如果这给您带来了安全隐患,则另一种选择是仅将辅助JWT令牌用于Web套接字内容

创建一个用于生成此JWT的REST端点,当然,只有使用您的主要登录令牌(通过标头传输)进行身份验证的用户才能访问该端点。 Web套接字JWT的配置可以与您的登录令牌不同,例如超时时间较短,因此作为升级请求的查询参数发送出去比较安全。

为注册SockJS eventbusHandler的同一路由创建一个单独的JwtAuthHandler 。确保首先注册了身份验证处理程序,以便您可以针对数据库检查Web套接字令牌(JWT应该以某种方式链接到后端的用户)。

答案 2 :(得分:0)

  

我认为保护Web套接字的最佳方法是使用CORS检查

跨源资源共享是一种允许请求资源的安全机制

router.route().handler(CorsHandler.create(your host origin path).allowCredentials(true));

我们还可以使用sockjs添加更多安全层:

允许事件总线桥进/出指定地址的事件

 BridgeOptions opts = new BridgeOptions()
          .addInboundPermitted(new PermittedOptions().setAddressRegex(Constants.INBOUND_REGEXP));