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

Add generic Google handlers #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ jobs:

- run: npm run-script build-ci okta_native
- run: test -f distributions/okta_native/okta_native.zip
- run: npm run-script build-ci google hosted-domain
- run: test -f distributions/google/google-hosted_domain.zip
- run: npm run-script build-ci google email-lookup
- run: test -f distributions/google/google-email_lookup.zip
- run: npm run-script build-ci rotate_key_pair
- run: test -f distributions/rotate_key_pair/rotate_key_pair.zip

Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ jobs:

- name: Build okta_native
run: npm run-script build-ci okta_native
- name: Build google-hosted_domain
run: npm run-script build-ci google hosted-domain
- name: Build google-email_lookup
run: npm run-script build-ci google email-lookup
- name: Build rotate_key_pair
run: npm run-script build-ci rotate_key_pair

Expand All @@ -49,6 +53,24 @@ jobs:
asset_path: ./distributions/okta_native/okta_native.zip
asset_name: okta_native_${{ steps.get_variables.outputs.tag_name }}.zip
asset_content_type: application/zip
- name: Upload google-hosted_domain
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./distributions/google/google-hosted_domain.zip
asset_name: google-hosted_domain_${{ steps.get_variables.outputs.tag_name }}.zip
asset_content_type: application/zip
- name: Upload google-email-lookup
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./distributions/google/google-email_lookup.zip
asset_name: google-email_lookup_${{ steps.get_variables.outputs.tag_name }}.zip
asset_content_type: application/zip
- name: Upload rotate_key_pair
uses: actions/upload-release-asset@v1
env:
Expand Down
36 changes: 27 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The build script prompts you for the required configuration parameters, which ar

### Generic Packages

A generic package retrieves its configuration at runtime from the [AWS Systems Manager](https://aws.amazon.com/systems-manager/) Parameter Store and [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/). Currently, support for this type of package has been added for OKTA Native only. To disable all issued JWTs, rotate the key pair using the Secrets Manager console.
A generic package retrieves its configuration at runtime from the [AWS Systems Manager](https://aws.amazon.com/systems-manager/) Parameter Store and [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/). Currently, support for this type of package has been added for OKTA Native and Google only. To disable all issued JWTs, rotate the key pair using the Secrets Manager console.

Generic packages are available for download from the Releases page of this GitHub repository. Or, to build a generic package yourself, execute:

Expand All @@ -39,8 +39,11 @@ Generic packages are available for download from the Releases page of this GitHu
The supported values of `package` are:

* `okta_native` - builds a generic Lambda package for OKTA Native authentication
* `google hosted-domain` - builds a generic Lambda package for Google authentication, using hosted domain authentication
* `google email-lookup` - builds a generic Lambda package for Google authentication, using JSON email lookup authentication
* `rotate_key_pair` - builds a Lambda package for rotating the RSA keys in AWS Secrets Manager


## Identity Provider Guides

### Github
Expand All @@ -62,14 +65,28 @@ The supported values of `package` are:
1. Create an **OAuth Client ID** from the **Create credentials** menu
1. Select **Web application** for the Application type
1. Under **Authorized redirect URIs**, enter your Cloudfront hostname with your preferred path value for the authorization callback. Example: `https://my-cloudfront-site.example.com/_callback`
1. Execute `./build.sh` in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.
1. Choose `Google` as the authorization method and enter the values for Client ID, Client Secret, Redirect URI, Hosted Domain and Session Duration
1. Select the preferred authentication method
1. Hosted Domain (verify email's domain matches that of the given hosted domain)
1. JSON Email Lookup
1. Enter your JSON Email Lookup URL (example below) that consists of a single JSON array of emails to search through
1. Google Groups Lookup
1. [Use Google Groups to authorize users](https://github.com/Widen/cloudfront-auth/wiki/Google-Groups-Setup)
1. Decide on whether you want to use a custom package or a generic package
* For a custom package:
1. Execute `./build.sh` in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.
1. Choose `Google` as the authorization method and enter the values for Client ID, Client Secret, Redirect URI, Hosted Domain and Session Duration
1. Select the preferred authentication method
1. Hosted Domain (verify email's domain matches that of the given hosted domain)
1. JSON Email Lookup
1. Enter your JSON Email Lookup URL (example below) that consists of a single JSON array of emails to search through
1. Google Groups Lookup
1. [Use Google Groups to authorize users](https://github.com/Widen/cloudfront-auth/wiki/Google-Groups-Setup)
1. Find the resulting `zip` file in your distribution folder
* For a generic package:
1. Create the parameters below in the AWS Systems Manager Parameter Store in the `us-east-1` region. Replace `{name}` with the name that you will give the Lambda authentication function.
* `/{name}/client-id` (The Oauth Client ID, above)
* `/{name}/client-secret` (The Oauth Client Secret, above; this can be stored as a SecureString in parameter store)
* `/{name}/domain-name` (e.g. `my-site.cloudfront.net`)
* `/{name}/hosted-domain` (if using the `google-hosted_domain` provider)
* `/{name}/json-lookup-endpoint` (if using the `google-email_lookup` provider)
* `/{name}/callback-path` (e.g. `/_callback`)
* `/{name}/session-duration` (in seconds)
1. Download the latest `google-hosted-domain.zip` or `google-email_lookup.zip` asset from the Releases page

1. Upload the resulting `zip` file found in your distribution folder using the AWS Lambda console and jump to the [configuration step](#configure-lambda-and-cloudfront)

### Microsoft Azure
Expand Down Expand Up @@ -162,6 +179,7 @@ The supported values of `package` are:
1. Download the latest `okta_native_*.zip` asset from the Releases page
1. Upload the `zip` file using the AWS Lambda console and jump to the [configuration step](#configure-lambda-and-cloudfront)


## Configure Lambda and CloudFront

See [Manual Deployment](https://github.com/Widen/cloudfront-auth/wiki/Manual-Deployment) __*or*__ [AWS SAM Deployment](https://github.com/Widen/cloudfront-auth/wiki/AWS-SAM-Deployment)
Expand Down
72 changes: 40 additions & 32 deletions authn/openid.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,56 @@ const cookie = require('cookie');
const jwkToPem = require('jwk-to-pem');
const auth = require('./auth.js');
const nonce = require('./nonce.js');
const cfg = require('./config.js');
const axios = require('axios');
var discoveryDocument;
var jwks;
var config;

exports.handler = (event, context, callback) => {
if (typeof jwks == 'undefined' || typeof discoveryDocument == 'undefined' || typeof config == 'undefined') {
config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
cfg.getConfig('config.json', context.functionName, function(error, result) {
if (error) {
console.log("Internal server error: " + error.message);
internalServerError(callback);
} else {
config = result;

// Get Discovery Document data
console.log("Get discovery document data");
axios.get(config.DISCOVERY_DOCUMENT)
.then(function(response) {
console.log(response);
// Get Discovery Document data
console.log("Get discovery document data");
axios.get(config.DISCOVERY_DOCUMENT)
.then(function(response) {
console.log(response);

// Get jwks from discovery document url
console.log("Get jwks from discovery document");
discoveryDocument = response.data;
if (discoveryDocument.hasOwnProperty('jwks_uri')) {
// Get jwks from discovery document url
console.log("Get jwks from discovery document");
discoveryDocument = response.data;
if (discoveryDocument.hasOwnProperty('jwks_uri')) {

// Get public key and verify JWT
axios.get(discoveryDocument.jwks_uri)
.then(function(response) {
console.log(response);
jwks = response.data;
// Get public key and verify JWT
axios.get(discoveryDocument.jwks_uri)
.then(function(response) {
console.log(response);
jwks = response.data;

// Callback to main function
mainProcess(event, context, callback);
})
.catch(function(error) {
console.log("Internal server error: " + error.message);
// Callback to main function
mainProcess(event, context, callback);
})
.catch(function(error) {
console.log("Internal server error: " + error.message);
internalServerError(callback);
});
} else {
console.log("Internal server error: Unable to find JWK in discovery document");
internalServerError(callback);
});
} else {
console.log("Internal server error: Unable to find JWK in discovery document");
internalServerError(callback);
}
})
.catch(function(error) {
console.log("Internal server error: " + error.message);
internalServerError(callback);
});
}
})
.catch(function(error) {
console.log("Internal server error: " + error.message);
internalServerError(callback);
});
}
});
} else {
mainProcess(event, context, callback);
}
Expand Down Expand Up @@ -175,12 +183,12 @@ function mainProcess(event, context, callback) {
{
"audience": headers.host[0].value,
"subject": auth.getSubject(decodedData),
"expiresIn": config.SESSION_DURATION,
"expiresIn": parseInt(config.SESSION_DURATION),
"algorithm": "RS256"
} // Options
), {
path: '/',
maxAge: config.SESSION_DURATION
maxAge: parseInt(config.SESSION_DURATION)
})
},
{
Expand Down
Loading