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?
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!