ether / ep_openid_connect

Etherpad plugin to authenticate users against an OpenID Connect provider
Other
5 stars 8 forks source link

Publish Status Backend Tests Status

ep_openid_connect

Etherpad plugin to authenticate users against an OpenID Connect provider.

It uses provider discovery to keep configuration simple.

Unlike other auth plugins, this one is not based around passport, for simplicity.

This is a fork of ep_openid-client.

Configuration

The plugin expects an ep_openid_connect block in the settings, with this structure:

  "ep_openid_connect": {
    "issuer": "https://id.example.com",
    "client_id": "MY CLIENT ID",
    "client_secret": "MY CLIENT SECRET",
    "base_url": "https://pad.example.com"
  },
  "requireAuthentication": true,

OAuth/OpenID Connect redirect URL (a.k.a. callback URL): https://pad.example.com/ep_openid_connect/callback

Etherpad's requireAuthentication setting must be true.

Configuration Details

Interaction with the users Setting

When a user authenticates, the value of the sub (subject) claim is used as the user's username in Etherpad. (The sub claim is the identity provider's unique identifier for the user.) Many identity providers (such as GitLab) identify users by a numeric user ID, so the sub claim (and thus the Etherpad username) will probably look something like "5374".

Each authenticated user gets their own account object. Default properties for a user's account object come from the users setting in settings.json. Etherpad uses the is_admin, readOnly, and canCreate properties to control access, and the ep_user_displayname plugin uses the displayname property for the name displayed in the user list. For example, the following sets the default display name to "Firstname Lastname" and the default access to read-only for the user identified by "5374":

  "users": {
    "5374": {
      "displayname": "Firstname Lastname",
      "readOnly": true
    }
  },

To avoid unintentionally applying values to users authenticated via this plugin, you can use the prohibited_usernames settings to force an authentication error if the sub claim happens to match. This is useful for preventing a malicious identity provider from gaining admin access to your Etherpad instance.

Controlling user account object properties with user_properties

The user_properties setting can be used to automatically add, remove, or change properties on a user's account object when the user authenticates. The user_properties setting maps a property name to a descriptor object that describes how the property's value is obtained:

Furthermore:

Example:

  "ep_openid_connect": {
    "user_properties": {
      "fromClaimWithDefault": {
        "claim": "claimName",
        "default": "default value"
      },
      "fromClaimOrUnset": {
        "claim": "claimName"
      },
      "fixedValue": {
        "default": "fixed value"
      },
      "forcedUnset": null
    }
  },

The above example sets properties as follows:

You can use this feature to control access in the OpenID Connect provider if it provides suitable claims:

  "ep_openid_connect": {
    "scope": ["openid", "etherpad"],
    "user_properties": {
      "is_admin": {"claim": "etherpad_is_admin"},
      "readOnly": {"claim": "etherpad_readOnly"},
      "canCreate": {"claim": "etherpad_canCreate"}
    }
  },

To avoid breaking assumptions made by Etherpad, the username property cannot be altered via the user_properties setting.

Interaction with the ep_guest Plugin

The ep_guest plugin creates a user that is used for all guest accesses. It is recommended you add the username you chose for the guest user to the prohibited_usernames setting. If the identity provider ever uses that username in the sub claim, you will get an obvious error instead of a mysterious inability to edit pads.

Interaction with the ep_user_displayname Plugin

By default, this plugin sets the user's displayname property to the value of the name claim. The ep_user_displayname plugin uses this property (and the displaynameChangeable property) to control the name displayed in the pad's list of users.

You can change the claim used to get the displayname:

  "ep_openid_connect": {
    "user_properties": {
      "displayname": {"claim": "nickname"}
    }
  },

Or you can cancel the default behavior:

  "ep_openid_connect": {
    "user_properties": {
      "displayname": {}
    }
  },

Interaction with Etherpad's Built-in HTTP Basic Authentication

If the user has not yet successfully authenticated, this plugin defers the access decision—it does not explicitly deny access. This causes Etherpad to fall back to another authentication plugin (if one is installed) or to the built-in HTTP basic authentication.

Note: This plugin installs an authentication failure handler, so the user will not get a 401 error that causes the browser to prompt for a username and password for HTTP basic auth. To fall back to HTTP basic authentication, the user's browser must proactively set the Authorization: Basic <credentials> header.

Interaction with Authorization Plugins

This plugin sets req.session.user to the user's settings object from settings.json and sets req.session.user.username to the user's username (the sub claim). Etherpad's built-in HTTP basic authentication does the same thing, so any authorization plugin designed to work with Etherpad's built-in authentication should work with this plugin.

Support

Currently only tested against GitLab instances.

Copyright and License

Copyright © 2020 Stefano Rivera stefano@rivera.za.net\ Copyright © 2020-2021 Richard Hansen rhansen@rhansen.org

Licensed under the MIT/Expat license.

This is a fork of ep_openid-client by Stefano Rivera, which is based on ep_oauth2 and ep_oidc.