I’m having trouble with connecting mqtt broker with pre-signed url which looks like :
wss://…eu-central-1.amazonaws.com/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=…&X-Amz-Date=20211004T170341Z&X-Amz-SignedHeaders=host&X-Amz-Signature=…2e&X-Amz-Security-Token=…
This is my implementation, but keep throwing 403 forbidden error. When I test with MQTTExplorer, it connects successfully with the signed url. The screenshot shows how I set up the configuration
Thank you for your interest HiveMQ and trying our HiveMQ Client library! We are happy to help you with your use case. Could you please clarify, what exactly are you trying to achieve?
com.hivemq.client.mqtt.exceptions.ConnectionFailedException: io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: Invalid handshake response getStatus: 403 Forbidden
Caused by: io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: Invalid handshake response getStatus: 403 Forbidden
at io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker13.verify(WebSocketClientHandshaker13.java:274)
at io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker.finishHandshake(WebSocketClientHandshaker.java:302)
at com.hivemq.client.internal.mqtt.handler.websocket.MqttWebsocketHandshakeHandler.finishHandshake(MqttWebsocketHandshakeHandler.java:103)
at com.hivemq.client.internal.mqtt.handler.websocket.MqttWebsocketHandshakeHandler.channelRead(MqttWebsocketHandshakeHandler.java:94)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:321)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:295)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1486)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1235)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1282)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:498)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:437)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
for the Secure WebSocket you should use “wss” instead of “tcp” or “mqtt”, and for insecure WebSocket you should use “ws”.
If you want us to check your code, you are of course welcome to post it. Please make sure that it is clear, which port you are using and how your password is encoded before it is being sent.
If you are suspecting that this is a HiveMQ cloud broker issue (which of course could happen), please also test your code with some other MQTT Broker having similar encryption and authorisation method. For example, with test.mosquitto.org:8885
Thanks for the reply.
I’ve already shared my code, and I didn’t found any documentation that I can follow regarding a secure websocket connection with a pre-signed url from AWS.
So I have a url from AWS like this one:
Then I create a websocket config and a mqtt3client:
val mqttWebSocketConfig = MqttWebSocketConfig.builder()
.subprotocol("wss")
.serverPath("mqtt")
.queryString(queryString)
.build()
val client: Mqtt3BlockingClient = Mqtt3Client.builder()
.identifier("9146AC3BD50778C0DB5125D7B4BFC3F2")
.serverHost("xxxxxxxxx-ats.iot.eu-central-1.amazonaws.com")
.serverPort(443)
.webSocketConfig(mqttWebSocketConfig)
.buildBlocking()
client.connect()
So my questions are:
What is supposed to put on the subprotocol? (I’ve tried “wss” and “mqtt”)
The queryString is supposed to have the path? (I’ve tried with “/mqtt?” and without in the query)
The server host is supposed to have the “wss://”?
I’m getting this error now after changing to subprotocol wss:
2022-02-18 19:17:05.862 3416-3972/com.witsoftware.vodafonetv E/IotSDK: MqttClientDisconnectedListener, message=io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: handshake timed out after 1000ms
2022-02-18 19:17:05.863 3416-3972/com.witsoftware.vodafonetv E/IotSDK: MqttClientDisconnectedListener
com.hivemq.client.mqtt.exceptions.ConnectionFailedException: io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: handshake timed out after 1000ms
Caused by: io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: handshake timed out after 1000ms
at com.hivemq.client.internal.mqtt.handler.websocket.MqttWebsocketHandshakeHandler.lambda$startHandshake$0$MqttWebsocketHandshakeHandler(MqttWebsocketHandshakeHandler.java:81)
at com.hivemq.client.internal.mqtt.handler.websocket.-$$Lambda$MqttWebsocketHandshakeHandler$wYOfs1pg0IXSdoZkmsItb8ZH5j8.run(Unknown Source:4)
at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:170)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:920)
Are you already signed up for a free hivemq cloud account? Once you are signed, to go your cluster and click Manage Cluster → Getting started. In the list of sample client find one that says Java(Websocket) hivemq-mqtt-client:
subprotocol is not explicitly updated, it is, by default, “mqtt”;
serverPath is “mqtt” (like in your last attempt);
there is a call to .applyWebSocketConfig() before .buildBlocking();
Please try to change your code this way and let us know the result. For the queryString use the part of the string that follows the “?”: “protocol://host:port/mqtt?xxx-xxx-xxx-xxx-xxx-x…”
I got it working by patching hivemq-mqtt-clint/src/main/java/com/hivemq/client/internal/mqtt/handler/websocket/MqttWebSocketInitializer.java.
Background: The signed websockets URL that should be used to connect to AWS IoT Core is already encoded. When the URI is generated for the websockets connection java.net.URI encodes the URI a second time and thus invalidates the signed websockets URL.
Therefore the second encoding must be reverted.
The following snippet made it working for me:
final URI uri;
final URI _uri;
try {
final MqttClientTransportConfigImpl transportConfig = clientConfig.getCurrentTransportConfig();
final InetSocketAddress serverAddress = transportConfig.getServerAddress();
_uri = new URI((transportConfig.getRawSslConfig() == null) ? "ws" : "wss", null,
serverAddress.getHostString(), serverAddress.getPort(), "/" + webSocketConfig.getServerPath(),
webSocketConfig.getQueryString(), null);
uri = new URI(URLDecoder.decode(_uri.toString(), StandardCharsets.UTF_8.toString()));
System.out.println("uri: " + uri);
} catch (final URISyntaxException e) {
onError.accept(channel, e);
return;
} catch (final UnsupportedEncodingException e) {
onError.accept(channel, e);
return;
}
DISCLAIMER: I am not a developer. There might be better options to revert the second encoding or prevent it from the beginning.
I am new to mqtt and developing a simple program using the HiveMQ client library. I am trying to connect to aws iot core with the endpoint provided by aws but I am getting this error message.
com.hivemq.client.mqtt.exceptions.ConnectionFailedException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
This is how i configure the client. I am seeking any advice and thank you all in advance.
Great to see your interest in HiveMQ!
To help you I would need to reproduce your error message, please provide exact steps to do that. In case if you are following somebody else’s instructions, like in a how-to article or from the textbook, please give me the link.
com.hivemq.client.mqtt.exceptions.ConnectionFailedException: io.netty.channel.ConnectTimeoutException: connection timed out: au1234m1uf12i-ats.iot.eu-west-1.amazonaws…com/“here the host ip”:443
Could you please support me by these errors and post a working example (with certificate if this is needed) on how to setup an MQTT connection to an amazon Broker with pre-signed url using proxy server?
Welcome to the HiveMQ Community! It’s great to see your enthusiasm for MQTT and the HiveMQ broker. We’re thrilled to have you onboard.
Regarding your query, I appreciate your interest in integrating AWS IoT Core MQTT broker with standard MQTT libraries. Indeed, according to AWS documentation Use AWS IoT Core MQTT broker with standard MQTT libraries, it’s advised to utilize a normal TLS-TCP connection on port 8883 instead of WebSocket or port 443.
If you have any further questions or need assistance, feel free to ask.
@Daria_H Thank you for quick reply. The Documentation of the broker I should connect to indicates that it uses Websockets protocol with port 443. That’s why I’m asking for an example on how to connect into it.
Thank you for support
@Hiben I understand your point. It would be helpful if you could share the link to the documentation you mentioned of how to connect to the broker using the WebSocket protocol on port 443. Thank you for your cooperation and support.
@Daria_H the documentation uses the libary Paho not hivemq. I diabled the proxy and now getting this error: com.hivemq.client.mqtt.exceptions.ConnectionFailedException: io.netty.handler.codec.http.websocketx.WebSocketClientHandshakeException: Invalid handshake response getStatus: 403 Forbidden
Like the previous posts. Could you please provide a running example for this case? The error appear n most of the posts since years but there is no concrete fix for that
Thank you for reaching out. It seems there might have been a small oversight in your message? If you intended to include a link to “The Documentation of the broker I should connect to indicates that it uses Websockets protocol with port 443,” please feel free to add it at your convenience.
@Daria_H I could already connect to the Broker with using the 443 port and Paho Libary but this libary doesn’t have a proxy support like Hivemq. So I’m sure that it is the right port. I can not provide an internal documentation.
Again could you please provide support on how to connect to an amazon presigned url using hivemq and fix the Handshake exception mentioned in most of the posts?