hivemq

How to get client username in PublishInboundInterceptor in HiveMQ


IN PublishInboundInterceptor, I can get client id, then I guess I can get username use ClientService, but I failed.

Is there a way to get client username and password?


Solution

  • there is no out of the box method to fetch username/password in the PublishInboundInterceptor. You would have to fetch the credentials via SimpleAuthenticator, EnhancedAuthenticator or ClientLifecycleEventListener#onMqttConnectionStart and then store them in the ConnectionAttributeStore (this is a store each client has for himself and stores attributes that are deleted when the client disconnects).

    I put together an example to showcase this:

    // use a SimpleAuthenticator to store username/password (if they are set by the client) in the connection attribute store of the client
    // other options to fetch username/password: ClientLifecycleEventListener#onMqttConnectionStart or EnhancedAuthenticator
    Services.securityRegistry().setAuthenticatorProvider(providerInput ->
            (SimpleAuthenticator) (simpleAuthInput, simpleAuthOutput) -> {
                final ConnectionAttributeStore connectionAttributeStore = simpleAuthInput.getConnectionInformation().getConnectionAttributeStore();
                final ConnectPacket connectPacket = simpleAuthInput.getConnectPacket();
    
                connectPacket.getUserName().ifPresent(username -> connectionAttributeStore.put("username", ByteBuffer.wrap(username.getBytes(StandardCharsets.UTF_8))));
                connectPacket.getPassword().ifPresent(password -> connectionAttributeStore.put("password", password));
            });
    
    // in the publish inbound interceptor fetch username/password from the connection attribute store (check optional if they are set)
    Services.initializerRegistry().setClientInitializer((initializerInput, clientContext) ->
            clientContext.addPublishInboundInterceptor(
                    (publishInboundInput, publishInboundOutput) -> {
                        final Optional<String> usernameOptional = publishInboundInput.getConnectionInformation().getConnectionAttributeStore().getAsString("username");
                        final Optional<@Immutable ByteBuffer> passwordOptional = publishInboundInput.getConnectionInformation().getConnectionAttributeStore().get("password");
    
                        //happy coding
                    }
            )
    );
    

    Hope this helps!