Keep client authentication state in session on server side

I would like to keep whether a client is authenticated or not on the server side within an enhanced authentication extension. I need to be able to distinguish subsequently whether a connected client is authenticated or not.

Is there a possibility to store custom session items on the broker? Or do I have to do it by myself within the extension? I expected this feature on the SessionInformation object, which can be fetched via the ClientService. Of course this state should only be mutable by the server.

Hey PremiumBurger,

we’re always happy to see interest and development around the community edition :slightly_smiling_face:

Can you please clarify what you are trying achieve? Is it, that you want to remove the need for clients
to re-authenticate upon reconnecting to the broker?

Best wishes,
Finn from the HiveMQ team

I implement an extension that allows clients to authenticate themselves. But it also allows clients to connect normally, without authentication. Additionally I implement a client-managed authorization which is only enabled for authenticated clients. This means that I have to be able to check whether a client is authenticated or not. It would be nice if I could store this information somewhere in the session that the broker manages anyway. Something like a key-value store which has the same lifetime as the session…

Your extension would need to implement its own cache for the necessary information.
It would be vital to clean this up (using session timeouts) in order to not fill memory over time.

package com.github.benmanes.caffeine.cache

private @NotNull Cache<String, ConcurrentSkipListSet<String>> createExpiryClientsCache(final int expireTime) {
    final Cache<String, ConcurrentSkipListSet<String>> cache = Caffeine.newBuilder()
            .expireAfterWrite(expireTime, TimeUnit.MINUTES)
            .build();
    return cache;
}

(only intended as a starting point)

The only other possibility would be access SessionAttributeStore which is only available for use with the Enterprise Extension SDK.

I hope this helps.

Kind regards,
Finn

1 Like

Hi @zingiber

Ok - I guess this would be the feature I am searching for.

I will either implement this by myself (thanks for the tip with the cache) or only allow authenticated clients anyway.

Thanks for your help!
Kind regards

I found that such Attributes can be written to the ConnectionAttributeStore even in CE extension SDK. This covers the functionality requested in my question. So in my opinion no custom cache is needed for this.

This store can be retrieved from ConnectionInformation which is available on most input parameters. For example:

publishInboundInput.getConnectionInformation().getConnectionAttributeStore()

If i understood the docs right, the SessionAttributeStore mentioned by @zingiber is part of the plugin SDK…

Hi Premiumburger,

it is correct, the SessionAttributeStore is part of the Enterprise extension SDK only, while the ConnectionAttributeStore is also available at the CE extension SDK.

The difference is that the key/value pairs added to the ConnectionAttributeStore have the same lifecycle as the client connection. (removed on disconnect)

The SessionAttributeStore on the other hand keeps the key/value pairs until the client session expires or the client reconnects with cleanstart/cleansession flag set to true.

Kind regards,
Florian

4 Likes

Thank you for your answer.

But is it somehow possible to read or iterate the ConnectionAttributes or rather the ConnectionInformation objects of all existing connections of the broker?

I would have expected this somewhere in the client services (Services.clientService()).

I would like to prevent that a non-authenticated client can connect with a client ID which is already taken by another client who has authenticated successfully. And whether a client has authenticated itself or not is noted in the ConnectionAttributes.

Or what other ways are there to prevent this - or to implement this behaviour?