-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3773593
commit 1bf923e
Showing
8 changed files
with
350 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"language": "Javascript", | ||
"sample_file": "./aws-iot-device-sdk-js-v2/samples/node/x509_connect", | ||
"sample_region": "us-east-1", | ||
"sample_main_class": "", | ||
"arguments": [ | ||
{ | ||
"name": "--endpoint", | ||
"secret": "ci/endpoint" | ||
}, | ||
{ | ||
"name": "--x509_cert", | ||
"secret": "ci/PubSub/cert", | ||
"filename": "tmp_certificate.pem" | ||
}, | ||
{ | ||
"name": "--x509_key", | ||
"secret": "ci/PubSub/key", | ||
"filename": "tmp_key.pem" | ||
}, | ||
{ | ||
"name": "--x509_endpoint", | ||
"secret": "ci/X509/endpoint_credentials" | ||
}, | ||
{ | ||
"name": "--x509_role_alias", | ||
"secret": "ci/X509/alias" | ||
}, | ||
{ | ||
"name": "--signing_region", | ||
"data": "us-east-1" | ||
}, | ||
{ | ||
"name": "--x509_thing_name", | ||
"data": "CI_PubSub_Thing" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# x509 Credentials Provider Connect | ||
|
||
[**Return to main sample list**](../../README.md) | ||
|
||
This sample is similar to the [Basic Connect](../basic_connect/README.md), but the connection uses a X.509 certificate | ||
to source the AWS credentials when connecting. | ||
|
||
See the [Authorizing direct calls to AWS services using AWS IoT Core credential provider](https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html) page for instructions on how to setup the IAM roles, the trust policy for the IAM roles, how to setup the IoT Core Role alias, and how to get the credential provider endpoint for your AWS account. | ||
|
||
Your IoT Core Thing's [Policy](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html) must provide privileges for this sample to connect. Below is a sample policy that can be used on your IoT Core Thing that will allow this sample to run as intended. | ||
|
||
<details> | ||
<summary>(see sample policy)</summary> | ||
<pre> | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Action": [ | ||
"iot:Connect" | ||
], | ||
"Resource": [ | ||
"arn:aws:iot:<b>region</b>:<b>account</b>:client/test-*" | ||
] | ||
}, | ||
{ | ||
"Effect":"Allow", | ||
"Action":"iot:AssumeRoleWithCertificate", | ||
"Resource":"arn:aws:iot:<b>region</b>:<b>account</b>:rolealias/<b>role-alias</b>" | ||
} | ||
] | ||
} | ||
</pre> | ||
|
||
Replace with the following with the data from your AWS account: | ||
* `<region>`: The AWS IoT Core region where you created your AWS IoT Core thing you wish to use with this sample. For example `us-east-1`. | ||
* `<account>`: Your AWS IoT Core account ID. This is the set of numbers in the top right next to your AWS account name when using the AWS IoT Core website. | ||
* `<role-alias>`: The X509 role alias you created and wish to connect using. | ||
|
||
Note that in a real application, you may want to avoid the use of wildcards in your ClientID or use them selectively. Please follow best practices when working with AWS on production applications using the SDK. Also, for the purposes of this sample, please make sure your policy allows a client ID of `test-*` to connect or use `--client_id <client ID here>` to send the client ID your policy supports. | ||
|
||
</details> | ||
|
||
## How to run | ||
|
||
To run the x509 Credentials Provider Connect sample use the following command: | ||
|
||
``` sh | ||
npm install | ||
node dist/index.js --endpoint <endpoint> --signing_region <signing region> --x509_cert <path to x509 cert> --x509_endpoint <x509 credentials endpoint> --x509_key <path to x509 key> --x509_role_alias <alias> -x509_thing_name <thing name> | ||
``` | ||
|
||
You can also pass a Certificate Authority file (CA) if your X509 certificate and key combination requires it: | ||
|
||
``` sh | ||
npm install | ||
node dist/index.js --endpoint <endpoint> --signing_region <signing region> --x509_cert <path to x509 cert> --x509_endpoint <x509 credentials endpoint> --x509_key <path to x509 key> --x509_role_alias <alias> -x509_thing_name <thing name> --x509_ca_file <path to x509 CA file> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
import { mqtt } from 'aws-iot-device-sdk-v2'; | ||
import { iot } from 'aws-iot-device-sdk-v2'; | ||
import { http } from 'aws-iot-device-sdk-v2'; | ||
import { auth } from 'aws-iot-device-sdk-v2'; | ||
import { io } from 'aws-iot-device-sdk-v2'; | ||
|
||
type Args = { [index: string]: any }; | ||
|
||
const yargs = require('yargs'); | ||
|
||
// The relative path is '../../util/cli_args' from here, but the compiled javascript file gets put one level | ||
// deeper inside the 'dist' folder | ||
const common_args = require('../../../util/cli_args'); | ||
|
||
yargs.command('*', false, (yargs: any) => { | ||
yargs.usage("Connect using X509."); | ||
common_args.add_universal_arguments(yargs); | ||
common_args.add_common_mqtt_arguments(yargs); | ||
common_args.add_common_websocket_arguments(yargs, true); | ||
common_args.add_x509_arguments(yargs); | ||
common_args.add_proxy_arguments(yargs); | ||
}, main).parse(); | ||
|
||
// Creates and returns a MQTT connection using a websockets and X509 | ||
function build_connection(argv: Args): mqtt.MqttClientConnection { | ||
|
||
/** | ||
* Pull data from the command line | ||
*/ | ||
const input_endpoint = argv.endpoint; | ||
const input_signing_region = argv.signing_region; | ||
const input_ca_file = argv.ca_file; | ||
const input_client_id = argv.client_id; | ||
|
||
const input_proxy_host = argv.proxy_host; | ||
const input_proxy_port = argv.proxy_port; | ||
|
||
const input_x509_endpoint = argv.x509_endpoint; | ||
const input_x509_thing_name = argv.x509_thing_name; | ||
const input_x509_role_alias = argv.x509_role_alias; | ||
const input_x509_cert = argv.x509_cert; | ||
const input_x509_key = argv.x509_key; | ||
const input_x509_ca_file = argv.x509_ca_file; | ||
|
||
/** | ||
* Set up and create the MQTT connection | ||
*/ | ||
|
||
let x509_tls_ctx_opt = new io.TlsContextOptions(); | ||
x509_tls_ctx_opt.certificate_filepath = input_x509_cert; | ||
x509_tls_ctx_opt.private_key_filepath = input_x509_key; | ||
if (input_x509_ca_file != null && input_x509_ca_file != undefined) { | ||
if (input_x509_ca_file.length > 0) { | ||
x509_tls_ctx_opt.ca_filepath = input_x509_ca_file; | ||
} | ||
} | ||
let x509_client_tls_ctx = new io.ClientTlsContext(x509_tls_ctx_opt); | ||
|
||
let x509_config = { | ||
endpoint: input_x509_endpoint, | ||
thingName: input_x509_thing_name, | ||
roleAlias: input_x509_role_alias, | ||
tlsContext: x509_client_tls_ctx, | ||
}; | ||
let x509_credentials_provider = auth.AwsCredentialsProvider.newX509(x509_config) | ||
|
||
let config_builder = iot.AwsIotMqttConnectionConfigBuilder.new_with_websockets({ | ||
region: input_signing_region, | ||
credentials_provider: x509_credentials_provider | ||
}); | ||
|
||
if (input_proxy_host) { | ||
config_builder.with_http_proxy_options(new http.HttpProxyOptions(input_proxy_host, input_proxy_port)); | ||
} | ||
|
||
if (input_ca_file != null && input_ca_file != undefined) { | ||
config_builder.with_certificate_authority_from_path(undefined, input_ca_file); | ||
} | ||
|
||
config_builder.with_clean_session(false); | ||
config_builder.with_client_id(input_client_id || "test-" + Math.floor(Math.random() * 100000000)); | ||
config_builder.with_endpoint(input_endpoint); | ||
|
||
// Create the MQTT connection from the configuration | ||
const config = config_builder.build(); | ||
const client = new mqtt.MqttClient(); | ||
return client.new_connection(config); | ||
} | ||
|
||
async function main(argv: Args) { | ||
common_args.apply_sample_arguments(argv); | ||
const connection = build_connection(argv); | ||
|
||
// force node to wait 20 seconds before killing itself, promises do not keep node alive | ||
// ToDo: we can get rid of this but it requires a refactor of the native connection binding that includes | ||
// pinning the libuv event loop while the connection is active or potentially active. | ||
const timer = setInterval(() => { }, 20 * 1000); | ||
|
||
console.log("Connecting..."); | ||
await connection.connect() | ||
console.log("Connection completed."); | ||
console.log("Disconnecting..."); | ||
await connection.disconnect() | ||
console.log("Disconnect completed."); | ||
|
||
// Allow node to die if the promise above resolved | ||
clearTimeout(timer); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "x509-connect", | ||
"version": "1.0.0", | ||
"description": "NodeJS IoT SDK v2 X509 Connect Sample", | ||
"homepage": "https://github.com/aws/aws-iot-device-sdk-js-v2", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/aws/aws-iot-device-sdk-js-v2.git" | ||
}, | ||
"contributors": [ | ||
"AWS SDK Common Runtime Team <[email protected]>" | ||
], | ||
"license": "Apache-2.0", | ||
"main": "./dist/index.js", | ||
"scripts": { | ||
"tsc": "tsc", | ||
"prepare": "npm run tsc" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^10.17.50", | ||
"typescript": "^4.7.4" | ||
}, | ||
"dependencies": { | ||
"aws-iot-device-sdk-v2": "file:../../..", | ||
"yargs": "^16.2.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
{ | ||
"compilerOptions": { | ||
/* Basic Options */ | ||
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ | ||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ | ||
// "lib": [], /* Specify library files to be included in the compilation. */ | ||
// "allowJs": true, /* Allow javascript files to be compiled. */ | ||
// "checkJs": true, /* Report errors in .js files. */ | ||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ | ||
"declaration": true, /* Generates corresponding '.d.ts' file. */ | ||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ | ||
"sourceMap": true, /* Generates corresponding '.map' file. */ | ||
// "outFile": "./", /* Concatenate and emit output to single file. */ | ||
"outDir": "./dist", /* Redirect output structure to the directory. */ | ||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ | ||
// "composite": true, /* Enable project compilation */ | ||
// "removeComments": false, /* Do not emit comments to output. */ | ||
// "noEmit": true, /* Do not emit outputs. */ | ||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */ | ||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ | ||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ | ||
/* Strict Type-Checking Options */ | ||
"strict": true, /* Enable all strict type-checking options. */ | ||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ | ||
"strictNullChecks": true, /* Enable strict null checks. */ | ||
"strictFunctionTypes": true, /* Enable strict checking of function types. */ | ||
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ | ||
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ | ||
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ | ||
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ | ||
/* Additional Checks */ | ||
"noUnusedLocals": true, /* Report errors on unused locals. */ | ||
// "noUnusedParameters": true, /* Report errors on unused parameters. */ | ||
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ | ||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ | ||
/* Module Resolution Options */ | ||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ | ||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ | ||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ | ||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ | ||
// "typeRoots": [], /* List of folders to include type definitions from. */ | ||
// "types": [], /* Type declaration files to be included in compilation. */ | ||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ | ||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ | ||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ | ||
/* Source Map Options */ | ||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ | ||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ | ||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ | ||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ | ||
/* Experimental Options */ | ||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ | ||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ | ||
}, | ||
"include": [ | ||
"*.ts" | ||
], | ||
"exclude": [ | ||
"node_modules", | ||
"dist" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters