Caching HTTP Responses in Authentication

Hi,

I am currently writing an Authentication Plugin for REST-based Authentication and Authorization.
I tumbled upon this thread https://stackoverflow.com/questions/21438069/hivemq-restful-authentication-plugin and I am wondering, why Caching should be necessary.
Of course, if clients are reconnecting very often, this might make sense. But in a scenario, where I expect a connection to be stable for days, is this really necessary? If implementing a cache, I would also like to evict cache every 1-2 hours, since I don’t want that clients can connect too long after I removed them.

B.t.w.: It looks to me, as if the support for caching has been removed in the current SDK version. Is there a reason for this?

Hello @schwinnez,

Nice to see your interest in MQTT security!

As far as your caching question is concerned, there are actually a few points that need to be addressed:

  1. A short caching time of the authentication data (e.g. if a client is who it claims to be) is useful to have as a rudimentary DOS protection. But an intrusion prevention software like Fail2Ban would be a much better tool for the job.

  2. Authorization data, on the other hand, profits greatly from caching. Of course it depends on your permissions structure, but if you implement something like RBAC, where the permissions associated with roles are usually very static (think administrator, user, etc.), it is possible to save a lot of computing and bandwidth.

Regarding the removed @Cached annotation. This was never intended for productive use and lead to a number of complications, not the least of them was an unlimited cache size. There are a couple of good and tested cache implementations for Java on Github.

Greetings
Georg

2 Likes

Thank for the really quick reply @sauroter =)

ad 1.) I think for our purposes, we would try to prevent/stop DOS and DDOS attack already in the network/transport layer. But for DOS protection at application layer, caching can certainly help.

ad 2.) We are currently using DefaultPermissions, which are retrieved at client connect time. So, the “REST”-Service is called only once for every client at connect time.

I decided to have caching configurable now and will observe the trade-offs of memory vs. computing performance/bandwidth in a load test environment.

What cache eviction period would you recommend in the RBAC setting you mentioned above?
I think, there is another trade-off here, since if permissions are revoked, you don’t want HiveMQ to still authorize the clients.

Best,
Christof

Hi @schwinnez,

I would recommend a rather aggressive caching time (hours to days) for RBAC role permissions.

It is usually much better to remove clients from roles than to change the permission structure of a role, as such a operation can have far flung consequences and should not be something done on the fly.

Have a nice day!
Georg

@sauroter, Thanks for the clarifications.
Another thing that I noticed in the documentation is that in the current sdk version you are also recommending to use async response for authentication and authorization. Since effectively, I need to block there, I am wondering about the advantages of using an async pattern here. Are the threads internally reused for other authentication/authorization requests in order to save memory?

Hi @schwinnez,

yes HiveMQ is by default very frugal (for a highly scalable, highly asynchronous system) with the number of spawned threads. This is to avoid unnecessary context switches. As such the threads in which SDK code is executed are often reused (after proper care for isolation is taken).

Especially for your use case, blocking in an extension callback, HiveMQ provides the ManagedExtensionExecutorService.

Greetings
Georg

By the way: A nice way to perform HTTP requests in Java, without blocking is the new HttpClient and its sendAsync() method. Just make sure to give it the ManagedExtensionExecutorService in the constructor as thread pool.