express-openid-connect-secured-jekyll

express-openid-connect-secured-jekyll

An Express application for securing a Jekyll powered website using OpenID Connect.

Express OpenID Connect Secured Jekyll

An Express application for securing a Jekyll powered website using OpenID Connect authorization_flow, with optional support for JavaScript clients using client_credentials.

Environment requirements

  • Node.js (v6 or v7 is set in package.json engines)
  • Ruby v2
  • gem install bundler

Usage quickstart

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/ritterim/express-openid-connect-secured-jekyll/master/install.rb)"

Or, with web.config included:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/ritterim/express-openid-connect-secured-jekyll/master/install.rb) - -w"

Manual usage

  • Copy package.json, npm-shrinkwrap.json, and server.js from this repository into the Jekyll site.
  • Create .env in the Jekyll site using .env.example as a template.
  • Add the following exclude items in the Jekyll site _config.yml:
    • node_modules/
    • package.json
    • npm-shrinkwrap.json
    • server.js
  • Add node_modules/ to .gitignore if the target is a Git repository and it does not already contain this entry.
  • Deploy the Jekyll blog as a Node.js application.

Configuration

Use a .env file at the repository root for local development using the following. For production scenarios, apply the following as environment variables as needed.

# Required
ISSUER=
AUTHORIZATION_URL=
TOKEN_URL=
USER_INFO_URL=
CLIENT_ID=
CLIENT_SECRET=
CALLBACK_URL=
EXPRESS_SESSION_SECRET=

# Optional
TOKEN_VALIDATION_URL=
CLIENT_CREDENTIALS_SCOPE=
SESSION_COOKIE_ALLOW_JS_ACCESS=
SET_BEARER_TOKEN_COOKIE_FOR_JAVASCRIPT=
PUBLIC_URLS=

# Production
EXPRESS_SESSION_REDIS_URL=
EXPRESS_SESSION_REDIS_KEY_PREFIX=

# Production (as needed)
TRUST_PROXY=

# Local development
EXPRESS_INSECURE=
Option (Bold if required) Description
ISSUER The issuer url. (https://example.org/)
AUTHORIZATION_URL The authorization url. (https://example.org/connect/authorize)
TOKEN_URL The token url. (https://example.org/connect/token)
USER_INFO_URL The user info url. (https://example.org/connect/userinfo)
CLIENT_ID The client id used for authentication.
CLIENT_SECRET The client secret for the CLIENT_ID.
CALLBACK_URL The callback url. (http://localhost:3000/callback for local development, adjust as necessary for production deployments)
EXPRESS_SESSION_SECRET A strong cryptographically secure random string.
TOKEN_VALIDATION_URL Setting this url enables bearer token authentication. (https://example.org/connect/accesstokenvalidation)
SESSION_COOKIE_ALLOW_JS_ACCESS JavaScript access of the cookie generated by express-session (set to true to enable).
SET_BEARER_TOKEN_COOKIE_FOR_JAVASCRIPT Creates a cookie with an access token for JavaScript clients when set to a truthy value.
CLIENT_CREDENTIALS_SCOPE A scope or scopes used with client_credentials authentication. Required if SET_BEARER_TOKEN_COOKIE_FOR_JAVASCRIPT is a truthy value. Separate multiple scopes with a space.
PUBLIC_URLS An optional comma and semicolon delimited string of public urls.
EXPRESS_SESSION_REDIS_URL Setting this url enables session persistance using Redis. Be sure to use transport security in production. (redis://:[password]@[hostname]:[port])
EXPRESS_SESSION_REDIS_KEY_PREFIX The Redis key prefix to use for the Express session (required when EXPRESS_SESSION_REDIS_URL is set). This value should be unique for each deployed site if using a shared Redis instance. A : is appended automatically.
TRUST_PROXY If 'trust proxy' should be set for Express based on the hosting environment (set to true).
EXPRESS_INSECURE HTTPS is required for the express-session generated cookie, unless this is set to true. This is useful for local development and should not be used in production.

Bearer token authentication

To enable bearer token authentication, set the TOKEN_VALIDATION_URL environment variable. A POST will be performed using application/x-www-form-urlencoded with the request body of token=the_token_value.

JavaScript usage

For scenarios when JavaScript on the page needs to make authenticated calls:

  • Set the SET_BEARER_TOKEN_COOKIE_FOR_JAVASCRIPT environment variable to true
  • Set the CLIENT_CREDENTIALS_SCOPE environment variable to your scope(s).

grant_type: client_credentials will be used for requesting a token. A cookie will be used with a default name of token. The cookie name can be overridden using the process.env.BEARER_TOKEN_COOKIE_NAME environment variable.

Public URLs

Set the PUBLIC_URLS environment variable using a comma or semicolon delimited string.

  • Specifying /assets will everything under that path.
  • Matches are case insensitive.
  • NOTE: Specifying a url of / will make the entire site public.

Example:

/assets, /2017/01/01/a-test-post.html

Development quickstart

  • cp .env.example .env
  • Add configuration in .env
  • npm install
  • npm start

If you encounter issues running locally with SSL certification validation, try adding NODE_TLS_REJECT_UNAUTHORIZED=0 to .env. This should only be done in a local development scenario. See https://stackoverflow.com/a/21961005 answering https://stackoverflow.com/questions/10888610/ignore-invalid-self-signed-ssl-certificate-in-node-js-with-https-request.

Development choices rationale

This repository is designed for being able to easily copy a small number of files into a Jekyll site to add authentication.

Author

Ritter Insurance Marketing https://www.ritterim.com

License

MIT