我想知道如何授权JS浏览器客户端接收受限制的出站SockJS事件总线消息。
我的js客户端设置正确(我认为),我有一个运行和工作的授权管理器,JS客户端可以登录并接收sessionID。
如果我添加" require_auths"到SockJSEventBusBridge配置外发消息被阻止,如果我从配置中删除它我收到消息。
如何将sessionID传递给registerHandler,以便服务器知道我被允许接收消息?
JS代码:
var eb = new vertx.EventBus('http://localhost:8080/eventbus');
eb.onopen = function() {
eb.send('vertx.basicauthmanager.login', {username: "user", password: "password"}, function (reply) {
console.log(reply);
if (reply.status === 'ok') {
console.log(reply.sessionID);
eb.registerHandler('test.stream', function(message) {
console.log(message);
});
} else {
alert('invalid login');
}
});
}
服务器端配置(Clojure):
(let [server (http/server)
auth-in [{:address "vertx.basicauthmanager.login"}]
auth-out [{:address "test.stream"
:requires_auth true}]]
(sockjs/bridge (sockjs/sockjs-server server) {:prefix "/eventbus"} auth-in auth-out)
(http/listen server 8080 "localhost"))
谢谢!
答案 0 :(得分:1)
正确的方法应该是首先从某个身份验证提供程序获取sessionID,然后发送sessionID,并将每个消息发送到protected(requiresAuth = true)地址。然后,该地址将调用EventBusBridgeHook的handleAuthorise()方法来检查是否允许该消息通过。
成功进行身份验证和授权后,您的会话ID将被记住(缓存)该特定套接字。如果存在为套接字缓存的会话ID,则将传递所有传出消息(您从客户端订阅的消息)。 所以这意味着当发送/发布消息时,vert.x会检查当前发送消息的权限,而不是从客户端注册地址的处理程序时。
因此,这意味着您应首先进行身份验证,然后将具有有效sessionID的消息发送到某个受保护的地址,以便vertx事件总线桥缓存您的会话ID。之后,您还可以从受保护的事件总线地址接收出站消息。
我做了一些简单的演示:https://github.com/michalboska/codingbeer-vertx/tree/auth-experiment(一定要使用auth-experiment分支,主分支没有实现任何身份验证)
编辑:vert.x的行为是正确的,你需要在你的javascript eventbus对象上设置sessionId,例如:
eb.sessionId='abcd.....';
https://github.com/eclipse/vert.x/pull/1008
PS:Vertx核心JAR中您可能感兴趣的方法是: org.vertx.java.core.sockjs.EventBusBridge#internalHandleRegister 和 org.vertx.java.core.sockjs.EventBusBridge#doSendOrPub