QWebSocketServer Authorization Mechanism
-
I want to develop a WebSocketServer which can check whether current user can connect to the server or not.
In my opinion, we can check the HTTP header "Authorization" when QWebsocketServer handshaking with client.The way to authorization:
- Login with username and password normally via HTTP
The following request is what our request look like:
And we will get a token from server if login successfully:POST /login HTTP/1.1 Host: foo.com Content-Type: application/json Cache-Control: no-cache { "username": "foo", "password": "bar" }
{"token": "authorization_token"}
- Add the token which we received from server to the "handshaking" request
I use Bearer token here for example.GET / HTTP/1.1 Accept-Encoding:gzip, deflate, sdch Accept-Language:en-GB,en-US;q=0.8,en;q=0.6 Authorization:Bearer authorization_token Cache-Control:no-cache Connection:Upgrade Upgrade: websocket
- Then check "Authorization" header in Server, if the token is valid, accept connection, otherwith, reject it.
I simplified 3 steps above into picture.
But I trace the source code, I found there is no way to implement this.
At line from 405 to 485 in file qtwebsockets/src/websockets/qwebsocketserver_p.cpp is the function: handshakeReceived()I recommend to add something in here:
if (request.isValid()) { QWebSocketCorsAuthenticator corsAuthenticator(request.origin()); Q_EMIT q->originAuthenticationRequired(&corsAuthenticator); /** * Here is start of my code */ if(authenticator != Q_NULLPTR) { if(!authenticator->validate(request.headers())) { // header invalid, try to close socket } } /** * Here is end of my code */ QWebSocketHandshakeResponse response(request, m_serverName, corsAuthenticator.allowed(), supportedVersions(), supportedProtocols(), supportedExtensions());
and the "authenticator" should be a class like this:
class QWebSocketAuthenticator : public QObject { Q_OBJECT public: QWebSocketAuthenticator() {} virtual QWebSocketAuthenticator() {} virtual bool validate(QMap<QString, QString> headers) = 0; }
Those developers who want to check whether to accept this incomming connection or not, just inherit this class and implement
validate()
function. - Login with username and password normally via HTTP
-
@FloatFlower.Huang you may want to check for some other authorization options for WebSockects, see this post for instance.
-
@Pablo-J.-Rogina
Thanks for your reply. But in the article you mentioned said that we can authenticate socket via cookie, or pass authorization header when connecting, but in QWebsocketServer, we can only access "origin" in header, so we cannot authenticate socket before accepting connection.
Furthermore , I think that authenticating socket after accepting connection is not a good way. Because attackers can initiate a lot of zombie websockets to connect to server, although these "zombie" do anything but they will occupy lots of resources of server.