This is an AWS Authorizer for OAuth2. It uses DynamoDB as a scalable cloud backend and leverages an existing OAuth2 Server library.
- AWS Account
- Node JS 12.x
- yarn
yarn
yarn dynamodb:install
yarn startAfter it has started, execute in another shell:
yarn dynamodb:migrateNow you have a clean, running OAuth2 server and client example.
yarn
yarn dynamodb:installyarn deployyarn startThen in another process
yarn dynamodb:migrateSetup the performance test using the password "jmeter" for the credentials. (JMeter is configured with that password as a default.)
yarn credential -l create jmeter
client -d -l create -C -R -A 'http://localhost:3000/callback' -P jmeter 'My test client'Get the client_id and client_secret
yarn client -l listNow run the test using the client_id and secret that you obtained.
yarn jmeter:run -Jclient_id=<client_id> -Jclient_secret=<client_secret>yarn start:remotedbA number of CLI tools exist for you to setup data for testing or development. These include scripts to:
- manage credentials,
yarn credential - manage clients,
yarn client - execute sample authorization code flows,
yarn authorize
You can run CUDL (create, update, delete, list) operations against the credentials table locally and remotely.
yarn credential --helpUsage: credential [options] [command]
Options:
-V, --version output the version number
-s, --stage [value] Stage of the service (default: dev)
-r, --region [value] AWS regin (default: us-west-2)
-d, --debug Show debug information
-l, --local Executes against local resources
-h, --help output usage information
Commands:
create <username> Add new credentials
update <username> Update existing credentials
delete <username> Remove existing credentials
list List all credentials
env Dump environment variables
You can run CUDL (create, update, delete, list) operations against the clients table locally and remotely.
yarn client --helpUsage: client [options] [command]
Options:
-V, --version output the version number
-s, --stage [value] Stage of the service (defaul
dev)
-r, --region [value] AWS regin (default: us-west-
-d, --debug Show debug information
-l, --local Executes against local resources
-h, --help output usage information
Commands:
create [options] <username> [description] Add a new client
update [options] <client> <username> [description] Update an existing client
delete <client> Remove an existing client
list List all clients
env Dump environment variables
You can execute authorization flows via the command line againt a locally running instance or a cloud instance.
yarn authorize --helpUsage: authorize [options] [command]
Options:
-V, --version output the version number
-s, --stage [value] Stage of the service (default: dev)
-r, --region [value] AWS regin (default: us-west-2)
-d, --debug Show debug information
-l, --local Executes against local resources
-h, --help output usage information
Commands:
code [options] <client_id> Generates and authorization code using client_id and state (recommended) with optional redirect URI and scope
password [options] <client_id> Authorize using username and password
client_credentials [options] <client_id> Authorize using client credentials
refresh_token [options] <client_id> <refresh_token> Authorize using a refresh token, client_id, and secret
env Dump environment variables
Setup the performance test using the password "jmeter" for the credentials. (JMeter is configured with that password as a default.)
yarn credential -l create jmeter
client -l create -C -R -A 'http://localhost:3000/callback' -P jmeter 'My test client'Get the client_id and client_secret.
yarn client -l listNow run the test using the client_id and client_secret that you obtained.
yarn jmeter:run -Jclient_id=<client_id> -Jclient_secret=<client_secret>Using the callback URL that you obtained for your deployment, setup the performance test using the password "jmeter" for the credentials. (JMeter is configured with that password as a default.)
yarn credential create jmeter
client create -C -R -A 'https://<prefix>.execute-api.<region>.amazonaws.com/<stage>>/callback' -P jmeter 'My test client'NOTE: The above URL will vary, and the above URL contains placeholders for what will vary. Those placeholders will be referred to below.
Get the client_id and client_secret.
yarn client listNow run the test using the client_id and client_secret that you obtained.
yarn jmeter:run -Jclient_id=<client_id> -Jclient_secret=<client_secret> \
-Jendpoint_protocol=https -Jendpoint_host=<prefix>.execute-api.<region>.amazonaws.com \
-Jendpoint_port=443 -Jendpoint_path=/<stage>You can manage credentials and clients stored on AWS in DynamoDB programmatically via lambda function calls.
In your applications you would only need to store the user_id as a reference to the credentials.
You would store the user profile with user_id as foreign key.
You can
Every event has an action and params.
| Attribute | Description | Default |
|---|---|---|
| action | Action to be performed | undefined |
| params | Parameters for the action to be performed | undefined |
Response:
| Attribute | Description |
|---|---|
| status | Either "ok" for success or "error" for error |
| response | Object returned with a "ok" status |
| error | Object returned with a "error" status |
| error.message | What went wrong |
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| username | The username for the credential | undefined | "homer" |
| password | The username for the credential | undefined | "dough.nuts" |
response:
A boolean value of true if authenticated by username and password, false otherwise.
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| username | The username for the credential | undefined | "homer" |
response:
An object representing the found unique credential with attributes:
| Attribute | Description |
|---|---|
| id | The id for the credential |
| username | The username for the credential |
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| id | The id for the credential | undefined | "00000000-0000-0000-0000-000000000000" |
response:
An object representing the found unique credential with attributes:
| Attribute | Description |
|---|---|
| id | The id for the credential |
| username | The username for the credential |
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| id | The id of the user | undefined | "00000000-0000-0000-0000-000000000000" |
| username | The username for the credential | undefined | "homer" |
| password | The password for the credential | undefined | "beer.n.donuts.4ever" |
response:
TODO
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| username | The username for the credential | undefined | "homer" |
response:
TODO
event.param:
None
response:
An array of objects representing credentials with attributes:
| Attribute | Description |
|---|---|
| id | The id for the credential |
| username | The username for the credential |
Every event has an action and params.
| Attribute | Description | Default |
|---|---|---|
| action | Action to be performed | undefined |
| params | Parameters for the action to be performed | undefined |
Response:
| Attribute | Description |
|---|---|
| status | Either "ok" for success or "error" for error |
| response | Object returned with a "ok" status |
| error | Object returned with a "error" status |
| error.message | What went wrong |
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| client_id | The id for the client | undefined | "00000000-0000-0000-0000-000000000000" |
response:
TODO
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| client_id | The id for the client | <uuid> | "00000000-0000-0000-0000-000000000000" |
| client_secret | The secret for the client | <string> | "000000000000000000000000000000000000000" |
| user_id | The id of the user | undefined | "00000000-0000-0000-0000-000000000000" |
| description | The description for the client | undefined | "lorem ipsum" |
| grants | An array of grants to be allowed by this client | undefined | [ "password", "client_credentials", "authorization_code", "refresh_token" ] |
| redirect_uris | An array of grants to be allowed by this client | undefined | [ "http://www.example.com/cb", "https://www.example.com/cb" ] |
response:
TODO
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| client_id | The id for the client | undefined | "00000000-0000-0000-0000-000000000000" |
response:
TODO
event.params:
| Attribute | Description | Default | Example |
|---|---|---|---|
| user_id | The id of the user | undefined | "00000000-0000-0000-0000-000000000000" |
response:
TODO
event.param:
None
response:
TODO
Some information is exported to allow for extension of this oauth2 and authentication implementaiton.
| Name | Description | Example |
|---|---|---|
| CredentialsTableName-{stage} | Name of the DynamoDB credentials table | CredentialsTableName-dev |
| CredentialsLambdaFunctionName-{stage} | Name of the credentials lambda function | CredentialsLambdaFunctionName-dev |
| ClientsLambdaFunctionName-{stage} | Name of the oauth2 clients lambda function | ClientsLambdaFunctionName-dev |
| OAuth2ServiceInternalEndpoint-{stage} | The endpoint to use internally | OAuth2ServiceInternalEndpoint-dev |