Open simutisernestas opened 3 years ago
Do you mean kind of authentication , like, https://github.com/RobotWebTools/rosbridge_suite/blob/a09a964fb5956321aca3b296da367e21d3d2e044/ROSBRIDGE_PROTOCOL.md#2-the-rosbridge-protocol?
Something like that, basically to only allow connection from authenticated parties. Either by implementing auth described by the protocol or restricting the access in other ways. Would be interesting to hear your opinion about any options on how to achieve that.
Sorry for the delay, we haven't had any plan to implement the auth function. Currently, the ros2-web-bridge
only offers some basic functions for the ROS2 system.
Would a PR be welcome?
Of course and you can share your idea using this thread to track the issue :)
nodejs ws library suggests auth through HTTP request by upgrading a client and forwarding to WebSocket connection. This seems quite straightforward and a much simpler option than implementing web bridge auth protocol. I've tested a dummy example here: https://github.com/simutisernestas/ros2-web-bridge/commit/c1759861164438781cdd0e7157892e24d01fe5a9#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346R115. Maybe it would be possible to take auth function as input from a user, which would decouple web bridge and client authorization and give a lot of flexibility when trying to achieve that. Let me know what do you think about this.
Also, the bridge buffer here https://github.com/simutisernestas/ros2-web-bridge/commit/c1759861164438781cdd0e7157892e24d01fe5a9#diff-c3f564a77784c0f2110861cc1cbb0cd3bfc98fe67af82d6b15396fe8d859128fR65 is not cleared if malformed input is sent. I think this is a bug.
Thanks for your investigations! I will take a look soon.
Hi @simutisernestas I have some questions
upgrade
request to take the auth, do developers send the request through the JS functions by roslibjs
or they have to send it explicitly by them self?bridge
receives the auth, who will be responsible to verify it? (I suppose the service vendor which the client wants to request should do this instead of the bridge
). upgrade
mechanism, it's for HTTP/1.1 only.roslibjs
as I understand here. There is no option to pass additional data like cookies, etc. I'm triggering upgrade
by simply connecting ws client to HTTP server port wscat -c ws://localhost:8080
and the connection is forwarded if authentication is successful. However, since roslibjs
doesn't support passing additional data this would require changing connect function. Ideally, you would do something similar as mentioned here if cookies are present in the request:**wsHttpServer**.on('upgrade', function (req, socket, head) {
var validationResult = validateCookie(req.headers.cookie);
if (validationResult) {
//...
} else {
socket.write('HTTP/1.1 401 Web Socket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
socket.close();
socket.destroy();
return;
}
//...
});
Good question. With the current toy example, you can simply bypass upgrading and connect directly to ws://localhost:9090
. Thus, authorization of the request must be handled too. What do you mean by service vendor? If I understand you correctly this would be handed over to a ROS2 node and authors providing the actual service implementation. Of course, this is possible but ROS2 users are taking advantage of many open-source packages which do not have such capabilities and those services would be open for attackers. Are there any other possibilities? Implementing authorization directly on the bridge seems cumbersome too.
HTTP wiki page states: "Like HTTP/2, HTTP/3 does not obsolete previous major versions of the protocol.". I don't think that HTTP/1.1 is going away in the foreseeable future. Please correct me if I'm missing something.
P.S. If you have any other ideas on how to achieve authentication & authorization for ros2 web clients would be nice to hear them and explore any possible solution/implementations.
There is no option to pass additional data like cookies,
If we cannot call roslibjs
directly, how can we take extra information used to authenticate? (considering running in a web browser without nodejs support)
service vendor
I mean if a client is sending requests to a service to do something (e.g. calculate the sum of two integer numbers), the service itself should decide whether to serve the request from a specific client.
As ROS2 uses DDS-Security, I'm wondering if we can leverage this feature? Some reference I found:
and there is an open issue for the sros in rclnodejs.
If we cannot call
roslibjs
directly, how can we take extra information used to authenticate? (considering running in a web browser without nodejs support)
One option would be to modify roslibjs
to take in extra arguments like cookies when initializing a connection. This would allow to implement authentication scheme as described previously. However, access control must be handled in the bridge too in that case.
As ROS2 uses DDS-Security, I'm wondering if we can leverage this feature?
As I understand SROS2 allows to restrict certain nodes from subscribing/publishing to selected topics. ros2-web-bridge
acts as a node in the network thus as far as SROS2 is concerned ros2-web-bridge
is acting as a single user. One could disable any publishing from this node, which would remove any possibility of unauthorized write to a system. Yet this does not cover all use cases. For instance, I would like to allow admin users to control a robot through a browser while prohibiting regular users to do so. Please correct me if I'm wrong.
So I think one feasible way is to extend the roslibjs
interfaces together with rosbridge v2 Protocol to support the scenario you described, right?
BTW, we are planing to have a working group for the WebRobotTools, so I think this is a good opportunity to move forward, because neither roslibjs
nor the rosbridge
was deigned for ROS2 and we can propose some ROS2 specific requirements under this working group, welcome to join:)
are there any updates on the authentication implementation? I'm trying to create a web interface that communicates with a ros2 robot through rosbridge_websocket and I would like to secure the connection through client authentication. Thank you very much
What's the state of the authentication system? How would you go about implementing it?