[Libwebsockets] Libwebsocket with Keycloak Integration

Andy Green andy at warmcat.com
Wed Apr 10 10:17:10 CEST 2019



On 10/04/2019 15:04, Marcel Isenbügel wrote:
> Hey everyone,
> 
> I’m interested to implement an authentication system to Websockets.
> 
> So they are two different ways.
> 
> 1.After upgrading to ws conncetion start an authorisation
> 
> 2.On the HTTP Request test the authorization

Lws natively supports Basic Auth using the http mount stuff... URLs that 
match the mount (so /secret/anything/etc if the mount was at /secret) 
cause the browser to prompt the user for credentials that must exist in 
a text file outside the served part of the filesystem.  It's "Basic" as 
the name says, but combined with TLS, it's better than nothing.

https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/http-server/minimal-http-server-basicauth

The Basic Auth support also covers ws upgrades on master, you need to 
add a pvo to the related vhost attached to the protocol name and with 
name "basic-auth" and value "path" where "path" is the path to the 
credentials file on the server.

See eg

https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/ws-server/minimal-ws-server-echo/minimal-ws-server-echo.c#n29-48

for how to add pvos.

> So I want to implement the second way. A Bearer Token will be send in 
> the http request. Is there a easy way to catch that token and check it 
> against a keycloak server.
> 
> I think I have to extract the http header when
> 
> LWS_CALLBACK_HTTP  is called ?
> 
> The Token is in the header => Authorization: Bearer <token>
> 
> How can I get this token ?

You should be able to get the headers for a non-upgrade HTTP request at 
LWS_CALLBACK_HTTP, but it might be worth trying 
LWS_CALLBACK_CHECK_ACCESS_RIGHTS

	/**< This gives the user code a chance to forbid an http access.
	 * `in` points to a `struct lws_process_html_args`, which
	 * describes the URL, and a bit mask describing the type of
	 * authentication required.  If the callback returns nonzero,
	 * the transaction ends with HTTP_STATUS_UNAUTHORIZED. */

in this case.  You would check the Authorization: header the usual way 
using token index WSI_TOKEN_HTTP_AUTHORIZATION with the api
lws_hdr_copy()

https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-http.h#n371-386

> On Success upgrade to ws
> 
> On Error decline connection
> 
> Is this a right and good way to implement this ? If someone has an 
> example it would be nice to see how it can works.

I'm not really clear what Keycloak is... if it's a network service 
itself, you will have to create an onward client connection and await 
the results before proceeding.  Lws only has the idea that you can 
immediately tell at the callbacks if it should proceed or not, as is the 
case with Basic Auth it either gave you valid credentials in the request 
header already, or it didn't... it doesn't have a way atm to defer 
judgement until later.  For ws upgrade, if you need an onward client 
connection, atm you'd need to take the approach to accept the connection 
but in the protocol don't do anything until the validity of the 
credential is known from the external service, or it times out waiting.

It probably needs a little more something in lws to support this 
deferred credential validity testing cleanly.

-Andy

> Best regards
> 
> Marcel
> 
> 
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> https://libwebsockets.org/mailman/listinfo/libwebsockets
> 


More information about the Libwebsockets mailing list