Skip to content
This repository has been archived by the owner on Feb 11, 2023. It is now read-only.

Custom OpenID Connect Providers

Payton Garland edited this page Dec 10, 2018 · 1 revision

Custom OpenID Connect Providers

Although cloudfront-auth has an automatic build process for the listed providers, it is likely that users will want to use other providers. As a result, you can manually build the project for an unsupported OpenID Connect provider.

Manual Build Steps

  1. Create a new directory in the distributions directory with your desired package name
  2. Copy package.json to your package directory
  3. Copy authn/openid.index.js to your package directory as index.js
  4. Run npm install
  5. Build the configuration file and save it as config.json in your package directory. Follow the config specifications.
  6. If any extra authorization step is needed, modify the authz/custom.js file accordingly. Regardless of modification, place the authz/custom.js file within your package directory and name it auth.js. Upon modification follow the authorization file specifications.
  7. Zip the following files:
    1. auth.js
    2. config.json
    3. index.js
    4. node_modules/*
    5. package-lock.json
    6. package.json
  8. Upload the zip to your AWS Lambda function

The Config

The configuration file was structured generically such that users can easily modify it without having to change the lambda. Data in the AUTH_REQUEST and TOKEN_REQUEST will be put in the querystring.

{
    "AUTH_REQUEST": {
        "client_id": "{client_id}",
        "response_type": "code",
        "scope": "openid email",
        "redirect_uri": "{redirect_uri_ending_in_callback_path}"
    },
    "TOKEN_REQUEST": {
        "client_id": "{client_id}",
        "client_secret": "{client_secret}",
        "redirect_uri": "{redirect_uri_ending_in_callback_path}",
        "grant_type": "authorization_code"
    },
    "DISTRIBUTION": "{custom_provider_name}",
    "AUTHN": "{custom_provider_name}",
    "PRIVATE_KEY": "{private_key}",
    "PUBLIC_KEY": "{public_key}",
    "DISCOVERY_DOCUMENT": "{discovery_document_url}",
    "SESSION_DURATION": {session_duration_int_in_seconds},
    "CALLBACK_PATH": "{callback_path}"
}

Here's an example configuration file for Google

{
    "AUTH_REQUEST": {
        "client_id": "redacted",
        "response_type": "code",
        "scope": "openid email",
        "redirect_uri": "https://example.com/_callback",
        "hd": "gmail.com"
    },
    "TOKEN_REQUEST": {
        "client_id": "redacted",
        "client_secret": "redacted",
        "redirect_uri": "https://example.com/_callback",
        "grant_type": "authorization_code"
    },
    "DISTRIBUTION": "Google",
    "AUTHN": "GOOGLE",
    "PRIVATE_KEY": "redacted",
    "PUBLIC_KEY": "redacted",
    "DISCOVERY_DOCUMENT": "https://accounts.google.com/.well-known/openid-configuration",
    "SESSION_DURATION": 10800,
    "CALLBACK_PATH": "/_callback",
    "HOSTED_DOMAIN": "gmail.com",
    "AUTHZ": "1"
}

The Authorization File

The authorization file has two main components used by openid.index.js

  1. isAuthorized(decoded, request, callback, unauthorized, internalServerError, config)
    • Responsible for determining if the given user is authorized to access the CloudFront distribution. Should you decide the user is unauthorized, call the unauthorized(body, callback) function that was passed in. (NOTE: you do not need to validate the JWT in this function, that step is handled for you in openid.index.js)
  2. getSubject(decoded)
    • Determines which value from the decoded JWT (received from OpenID Connect provider) to be set as the custom JWT subject. We create a new JWT and set it as a cookie for future access to the CloudFront distribution.
function isAuthorized(decoded, request, callback, unauthorized, internalServerError, config) {
  callback(null, request);
}

function getSubject(decoded) {
  return decoded.payload.email;
}

exports.isAuthorized = isAuthorized;
exports.getSubject = getSubject;