I have an IOT device that is not able to generate JWT token. For authenticating with Google IOT core, we need to create jwt token with expiry time. Is there any way to create a static authentication, like username and password as fixed, as it is for local mqtt broker (mosquitto) ?
I think your only solution is to add a proxy IoT client that is able to generate JWTs.
Your devices will message the proxy using whatever mechanism and security you want and the proxy would manage JWTs when communicating with IoT core.
See gateways
Related
I’ve got a use-case where my devices should make GET requests against my API gateway.
What would be the simplest way to have API gateway perform client authentication of the device? Is it possible to use the certificates already generated by IoT Core and used in MQTT?
Authorizing direct calls to AWS services using AWS IoT Core credential provider:
Devices can use X.509 certificates to connect to AWS IoT Core using TLS mutual authentication protocols. Other AWS services do not support certificate-based authentication, but they can be called using AWS credentials in AWS Signature Version 4 format. The Signature Version 4 algorithm normally requires the caller to have an access key ID and a secret access key. AWS IoT Core has a credentials provider that allows you to use the built-in X.509 certificate as the unique device identity to authenticate AWS requests. This eliminates the need to store an access key ID and a secret access key on your device.
I am working on an embedded device which is already able to communicate via MQTT with AWS and Azure for several years.
Now our customers want to be able to use MQTT with Google IoT Cloud as well.
I thought it would be nothing complicated, but I found that I have to generate a JWT token every 24 hours, which is quite heavy for an embedded device (especially a low power one) to handle, to generate a token via the RS256 algorithm, it takes 10 seconds, and with ES256 it takes 6 seconds, with an 80 MHz ARM Cortex-M4.
So I'm looking for a way to avoid having to generate this JWT token, I found in the documentation that Google supports MQTT gateways, but that means we have to keep a gateway server somewhere in the network, which is not very competitive considering what offer AWS and Azure.
Is there a way to avoid having to generate a JWT token (without having to manage an MQTT gateway)?
Or is there someone who offers an MQTT-Gateway service (also for a fee)?
Why did Google decide to use this JWT token as authentication? Wouldn't it have been easier to do as AWS and Azure did?
No, as per the current implementation, JWT tokens and MQTT gateway using the Association only authentication method are the only ways to authenticate to Cloud IoT Core.
I searched all over, tutorials, web, everybody jumps away without explaining(I understand why) the checkboxes in app client settings:
Enable sign-in API for server-based authentication
Only allow Custom Authentication
Enable username-password (non-SRP) flow for app-based authentication
The learn more link does not help me, lots of information and not so easy to understand, grasp. Can someone explain this settings?
Here is my take on the matter.
App client has several Auth Flow Configurations.
1. Enable username password auth for admin APIs for authentication (ALLOW_ADMIN_USER_PASSWORD_AUTH)
This enables Server-Side Authentication Flow. If you don't have an end-user app, but instead you're using a secure back end or server-side app.
2. Enable lambda trigger-based custom authentication (ALLOW_CUSTOM_AUTH)
This enables the Custom Authentication Flow. This can help you create a challenge/response-based authentication model using AWS Lambda triggers.
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html
Under User Pools -> Triggers you can see many lambda functions. You can use Create Auth Challenge, Define Auth Challenge and Verify Auth Challenge Response functions to create a custom authentication flow.
3. Enable username password based authentication (ALLOW_USER_PASSWORD_AUTH)
This enables Client Side Authentication Flow that uses user password-based authentication. In this flow, Cognito receives the password in the request.
You can use AWS Mobile SDK for Android, AWS Mobile SDK for iOS, or AWS SDK for JavaScript to implement this.
4. Enable SRP (secure remote password) protocol based authentication (ALLOW_USER_SRP_AUTH)
This is similar to the above flow in section 3. except for the password verification. This flow uses the SRP protocol to verify passwords.
http://srp.stanford.edu/whatisit.html
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserPoolClientType.html
5. Enable refresh token based authentication (ALLOW_REFRESH_TOKEN_AUTH)
After successful authentication, Amazon Cognito returns user pool tokens(Three tokens) to your app. You can use the tokens to grant your users access to your own server-side resources, or to the Amazon API Gateway. Or, you can exchange them for temporary AWS credentials to access other AWS services.
The three tokens are ID Token(JWT), Access Token, Refresh Token. The refresh token can be used to retrieve new ID and access tokens. Once you login to a mobile app, you are not needed to log in each time when you close and open the application and this functionality is implemented using refresh tokens.
https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
What about Amazon Cognito hosted UI ?
App clients can be configured to use built-in Cognito webpages for signing up and signing in users. When using the hosted UI you can enable both the Authorization code grant and the Implicit code grant, and then use each grant as needed.
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-idp-settings.html
Here is my attempt at explaining these options. Before that I would like to briefly mention about Oauth2, which is the protocol on which AWS Cognito is based.
In the context of AWS Cognito, Cognito itself is the Authentication (OAuth) server and also the Resource server (because we create users in Cognito user pool) and your app would be the Client (which sends the authentication request). The client has to first register itself with the OAuth server - this is what is being done in the "App clients" section of Cognito.
The recommended OAuth2 flow is Authorization Code Grant flow. In this flow,
i) The Client sends username/password to the OAuth Server.
ii) The OAuth server validates and calls back the client with a
authorization code.
iii) The Client again sends this code back to the OAuth server
iv) The OAuth server sends the tokens to the Client.
Please read the above linked article for more explanation on OAuth2.
Now explaining the options in Cognito App Client settings:
1. Enable sign-in API for server-based authentication
With this option, your client app can directly receive the tokens without having the additional step of first getting the authorization code.
There are Cognito APIs like AdminInitiateAuth, Admin-* which does this. However, these APIs require AWS admin credentials. Hence usually these calls are done by the backend server of the client app. The front-end can pass the username/password to the backend and the backend server can communicate with AWS Cognito and authorize the user.
2. Only allow Custom Authentication
Here you don't use the OAuth provided authorization code grant flow. Instead, you can define your own steps and challenges. Your client app can ask a secret question etc, before authenticating and giving tokens.
3. Enable username-password (non-SRP) flow for app-based authentication
This is the least safe flow. This skips the part of returning the authorization code and directly returns the tokens back to the client.
I hope this explains.
AWS IoT supports this via userPools, how this can be done via Google Cloud messaging? -Thanks
Cloud IoT Core recommends HTTP bridge for that. (https://cloud.google.com/iot/docs/how-tos/http-bridge)
To establish a connection to HTTP Bridge you have to prepare a private key signed JWT for authentication. The problems will be: where do you store the PK in a secure way in the browser session and how to make a relation between the browser user and IoT device identity?
Btw, 'Google Cloud Messaging' was not part of Google Cloud IoT, was a different product. Now Firebase Cloud Messaging is a recommended product https://firebase.google.com/docs/cloud-messaging/
use a JavaScript MQTT client, for example Eclipse Paho; this just needs an external IP.
I have an API which large number of devices connect to. These devices are distributed by us and can be considered as trusted. They do not have a built-in Web browser.
I'm considering to use OAuth Client Credentials flow (flow for machine-to-machine communication). However, I wonder if Cognito Client Credentials flow is not designed for this purpose as it allows only 25 App Clients.
Is there another OAuth flow (within Cognito) that can be used in this case?
I suppose Resource Owner Password Grant can be used here but can't figure out how to enable it in Cognito.