Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to connect to Iot Core AWS using ngx-mqtt 16.0.0 #234

Open
matiasAS opened this issue May 28, 2023 · 5 comments
Open

How to connect to Iot Core AWS using ngx-mqtt 16.0.0 #234

matiasAS opened this issue May 28, 2023 · 5 comments

Comments

@matiasAS
Copy link

matiasAS commented May 28, 2023

Hello, I need to connect to IoT Core using Angular 16 and [email protected]. I have tried all the methods. If I add 'protocolVersion:5' in the connection options, it returns the following error:

image

And without that option, the connection closes without connecting.

The connection options are as follows:
connectionIotCore: IMqttServiceOptions = {
hostname: 'xxxxxxxxxxxx-ats.iot.us-east-2.amazonaws.com',
port: 443,
protocol: 'wss',
path: '/mqtt',
protocolId: 'MQTT',
protocolVersion: 5,
clientId: localStorage.getItem('username') + '_' + uuidv4(),
rejectUnauthorized: false,
cert: `-----BEGIN CERTIFICATE-----

        -----END CERTIFICATE-----`, 
key: `-----BEGIN RSA PRIVATE KEY-----

        -----END RSA PRIVATE KEY-----`, 
ca: `-----BEGIN CERTIFICATE-----

      -----END CERTIFICATE-----`, 

}

and environment is:

image

I need to solve this problem urgently. I have tried all the possible methods that have come to mind. I'm not sure if I need to do something in the AWS console, in the connection settings, or if the browser is simply not compatible with an SSL connection using the certificate. Please note that it is Ionic, but I am working on it as a web page. The reason for choosing Ionic instead of pure Angular is that I am still unsure if my app will also be a mobile app or not.

Any solution, observation, comment, question, etc., that you can provide, I will be attentive to it.

@sclausen can you help me please?

Regards.

@sclausen
Copy link
Owner

I'm really sorry, but it seems I can't help you. I've never worked with AWS IoT Core and after a brief research, I didn't found a solution for mqtt.js, but the recommendation to use AWS own SDK for that case.
I would suggest you post this question on stackoverflow.com. There are probably more people who might have a solution.

@matiasAS
Copy link
Author

matiasAS commented May 29, 2023

@sclausen I have tried all the aws sdk libraries, and apparently they are compatible with javascript backend but not brower. That's why I ask how is the connection with ngx-mqtt since it is a very simple and easy to use library. At least with mosquitto with user/password authentication I can connect without problem, easy and fast.

I thought that by opening an issue on the github of the library there might be more direct help on a solution to my problem.

Can you keep the issue open in case someone else can help me?

@sclausen sclausen reopened this May 30, 2023
@sclausen
Copy link
Owner

sclausen commented Jun 7, 2023

Having a look at one of the official examples I would assume it wouldn't be a big task to create ngx-aws-mqtt5 or something. I don't know if many would use that lib though…

@Snappey
Copy link

Snappey commented Jul 15, 2023

Did some digging into this, the library 100% works with AWS IoT Core using secure websockets. The most painful part was the authentication/authorisation, I ended up just using a custom lambda authorisor to make it work without dealing with certificates, but I don't see any reason why you wouldn't be able to use certs instead. (As pointed out below mqtt.js does not support certificate based authentication in the browser)

Angular Config:

export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
  hostname: '<my_aws_endpoint?.iot.<my_aws_region>.amazonaws.com',
  port: 443,
  protocol: "wss",
  path: '/mqtt',
  username: "<my_username>",
  password: "<my_password>",
  protocolVersion: 5,
};

Lambda Authoriser:

const connectPolicy = {
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "iot:Connect"
    ],
    "Resource": [
      "arn:aws:iot:*:*:client/*"
    ],
  }, {
    "Effect": "Allow",
    "Action": [
      "iot:Publish", "iot:Receive", "iot:Subscribe"
    ],
    "Resource": [
      "arn:aws:iot:*:*:topic/*"
    ]
  }, {
    "Effect": "Allow",
    "Action": [
      "iot:Subscribe"
    ],
    "Resource": [
      "arn:aws:iot:*:*:topicfilter/*"
    ]
  }, ]
};

exports.handler = async (event, context) => {
  const response = {
    isAuthenticated: false,
    principalId: "ExampleUpdateThis",
    disconnectAfterInSeconds: 86400,
    refreshAfterInSeconds: 300,
    policyDocuments: [connectPolicy]
  };


  if (!event.protocolData?.mqtt) {
    return response;
  }

  const { username, password, clientId } = event.protocolData.mqtt;
  if (username !== "<change__username>" || Buffer.from(password, "base64")
    .toString() !== "<change_password>") {
    return response;
  }

  return JSON.stringify({
    ...response,
    isAuthenticated: true
  });
};

Do not use this this in production; hardcoded credentials for authorisation with a single user and policy is an open door, this is purely a proof of concept.

Once you've setup the authoriser it's just the same as connecting to any password protected broker, change the username and password to one your authoriser expects and its "good to go". If you're having any issues following this I used this and followed their troubleshooting steps

The other trick I found was to set the default authoriser for my endpoint via the API (or CLI), can do so by using the following aws iot set-default-authorizer --authorizer-name <Authoriser_Name> or see here.

Could see this potentially causing some issues, IoT Core expects you to pass a header with the initial http upgrade request identifiying the authorisor to use if a default one is not set, I didn't dive into the details of the library so not sure if it's possible to attach custom headers to make that possible.

Long story short, library works with IoT Core just the authentication can be a pain point.

@sclausen
Copy link
Owner

Thanks for sharing an approach with other users of this library.

[…] but I don't see any reason why you wouldn't be able to use certs instead.

Unfortunately, mqtt.js doesn't support certificates in the browser, so I don't see them as a viable solution for the authorization problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants