Skip to content

Authentication

Overview

ContainerProxy supports currently the following authentication/authorization back-ends:

  • LDAP and ActiveDirectory (the default)
  • Single-Sign On with Keycloak
  • OpenId Connect and services that implement it e.g. Auth0
  • Social authentication e.g. Facebook, Twitter, Google, Github or Linkedin
  • Simple authentication
  • No authentication

Authentication back-ends can be set using

proxy:
  authentication: ldap

using any of ldap (default), keycloak, openid, social, simple, or none.

LDAP

When using LDAP authentication, ContainerProxy will use the provided LDAP url to:

  • Authenticate users by attempting to bind with their login name and password.
  • Authorize users to access apps by searching for any LDAP groups they are a member of, and matching those group names to the list of group names configured for the app.

With the default values (authentication: ldap), authentication will be done against the LDAP server at ldap.forumsys.com; to log in one can use the user name "tesla" and password "password".

In order to use it with your own LDAP directory, you can use the following fields:

  • url: the LDAP connection string, composed of the URL and base DN of the LDAP directory;
  • user-dn-pattern: pattern of the distinguished name for a user. Use this if all your users are in a single LDAP location;
  • user-search-filter: LDAP filter to search for users. Use this if your users are in different LDAP locations, and you cannot use user-dn-pattern;
  • user-search-base: search base to search for users. Only used if user-search-filter is set;
  • group-search-filter: LDAP filter used to search for group memberships;
  • group-search-base: search base to search for groups. Only used if group-search-filter is set;
  • manager-dn: the distinguished name of the user used to bind to the LDAP directory; leave empty if the initial bind is anonymous;
  • manager-password: the password of the user used to bind to the LDAP directory; can be omitted if manager-dn is empty (i.e. when the initial bind is anonymous).

Notes:

  • the base DN given in the url (e.g. dc=example,dc=com in ldap://ldap.forumsys.com:389/dc=example,dc=com) does not have to be repeated in user-search-base or group-search-base. However, it must be repeated in the manager-dn.
  • user-dn-pattern and user-search-filter support the placeholder {0} which will be replaced with the user's login name.
  • group-search-filter supports three placeholders: {0} maps to the user's DN, {1} maps to the user's login name, and {2} maps to the user's CN.

Multiple LDAP providers

When multiple LDAP providers need to be configured (e.g. to support different domains or forests), this can be done using

proxy:
  ldap:
  - url: ldap://ldap.forumsys.com:389/dc=example,dc=com
    ...
  - url: ldap://another.ldap.server:389/...
    ...

instead of the single LDAP configuration

proxy:
  ldap:
    url: ldap://ldap.forumsys.com:389/dc=example,dc=com
    ...

StartTLS

Using LDAP with StartTLS can be achieved by adding a setting

proxy:
  ldap:
    starttls: simple

This setting may have the following values:

  • simple: StartTLS is enabled, using simple client authentication;
  • true: same as simple;
  • external: StartTLS is enabled, using external (certificate) client authentication;
  • (None): if the property is absent (default), StartTLS is disabled.

More information on the StartTLS extension can be found here.

Note:

  • LDAPS and LDAP with StartTLS are mutually exclusive; it is not possible to combine the two mechanisms.

Example: FreeIPA

When using a FreeIPA server for managing identities (e.g. the standard on RHEL), the configuration with the default directory tree will be:

ldap:
      url: ldaps://example.com:636/dc=example,dc=com
      manager-dn: uid=containerproxy,cn=sysaccounts,cn=etc,dc=example,dc=com
      manager-password: xxxxxxxxxxxx
      user-dn-pattern: uid={0},cn=users,cn=accounts
      group-search-filter: (member={0})
      group-search-base: cn=groups,cn=accounts

Notes:

  • in this example uid=containerproxy,cn=sysaccounts,cn=etc,dc=example,dc=com is a specific system account created to bind against the FreeIPA LDAP directory on behalf of ContainerProxy;

Example: Active Directory

ldap:
      url: ldaps://example.com:3269/dc=example,dc=com
      manager-dn: cn=containerproxy,ou=Service Accounts,dc=example,dc=com
      manager-password: xxxxxxxxxxxx
      user-search-filter: (sAMAccountName={0})
      group-search-filter: (member={0})
      group-search-base: ou=Groups

Notes:

  • sAMAccountName is often used as the unique login name in Active Directory environments. That's why it is used here in the user-search-filter.
  • 3269 is the SSL-enabled port for the Global Catalog.

Single-Sign On / Keycloak

A second type of authentication is Keycloak authentication, a very powerful option that delegates authentication and authorization to the open source identity and access management system Keycloak supported by Red Hat. Many advanced features are available to ContainerProxy such as User Federation, Identity Brokering and Social Login.

Keycloak authentication can be configured using

proxy:

  [...]

  authentication: keycloak

in the application.yml file. The details related to the application identifiers and secrets for each of the social platforms can be configured in a separate keycloak block:

proxy:

[...]

  keycloak:
    realm: yoursso
    auth-server-url: http://yoururl.com:8180/auth
    resource: yourresource
    credentials-secret: your-credentials-secret

Optionally, one can set the SSL/HTTPS mode using proxy.keycloak.ssl-required which can be set to one of none, all or external (default). These options are documented here.

Note:

  • the user name of the authenticated user is made available to the Shiny application via the environment variable SHINYPROXY_USERNAME;
  • the groups the authenticated user is member of are made available to the Shiny application via the environment variable SHINYPROXY_USERGROUPS.

Further documentation on setting up Keycloak can be found here.

OpenID Connect (OIDC)

OpenID Connect is a modern authentication protocol based on the OAuth2 standard. It uses tokens, removing the need to store passwords and offering a single-sign-on experience for desktop, web and mobile apps.

More information about OIDC can be found on the OpenID website.

To configure OIDC in ContainerProxy, several steps must be performed:

  1. Register your ContainerProxy installation with an OIDC provider.
  2. Obtain the configuration parameters for your OIDC provider that ContainerProxy requires.
  3. (Optional) For group-based authorization, add a custom claim in the OIDC ID Token.

Enable OIDC authentication

OIDC authentication can be enabled by setting

proxy:

  [...]

  authentication: openid

in the application.yml file.

Register with an OIDC Provider

Some examples of well-known OIDC providers are: Auth0, Okta, Google, Microsoft, and many more social platforms. Of course, you can also deploy your own OpenID identity provider.

When registering the application, make sure to select the type 'web application'. This allows you to specify a callback URL. The URL should look like this:

http(s)://(your-containerproxy-url)/login/oauth2/code/containerproxy

Defining an incorrect callback URL will result in authentication errors in ContainerProxy.

Set OIDC configuration parameters

Your OIDC provider should offer you the following parameters for your newly registered app:

  • Auth Endpoint URL: The URL where OIDC initiates authentication flows. ContainerProxy will redirect here when an unauthenticated user accesses a page.
  • Token Endpoint URL: The URL where tokens can be retrieved or exchanged. This is used during the authentication process.
  • JSON Web Key Set (jwks) URL: The URL where the provider's public certificates can be found. This is used during the authentication process.
  • Client ID: A unique ID generated by the provider for your application.
  • Client Secret: A secret generated by the provider for your application.

Enter these parameters into ContainerProxy's application.yml file. An example for Google is given below:

proxy:
  openid:
    auth-url: https://accounts.google.com/o/oauth2/v2/auth
    token-url: https://www.googleapis.com/oauth2/v4/token
    jwks-url: https://www.googleapis.com/oauth2/v3/certs
    client-id: ***
    client-secret: ***

Group-based authorization

While OIDC specifies an authentication flow, it has no notion of 'user groups' or 'permission levels'. To achieve this in ContainerProxy, you must use custom claims. Claims are pieces of information about the user that are included in the ID Token returned by the OIDC provider. Common claims include first name, last name, email address, etc.

Adding a custom claim to an ID Token is specific to each OIDC provider. Below is an example for Auth0.

  • Go to the user management page, select a user, and scroll down to the app_metadata block. Enter the following JSON:
{
  "containerproxy_roles": [ "scientists", "mathematicians" ]
}
  • Go to the rules page and create a new rule that attaches this information to the ID Token upon authentication:
function (user, context, callback) {
  context.idToken['https://containerproxy.io/containerproxy_roles'] = user.app_metadata.containerproxy_roles;
  callback(null, user, context);
}

Note that custom claims must have a URI-like namespace. In this example, we use the name https://containerproxy.io/containerproxy_roles.

  • In ContainerProxy's application.yml file, enter the full name of the custom claim containing the user's roles:
proxy:
  openid:
    roles-claim: https://containerproxy.io/containerproxy_roles

Social Authentication

A fourth type of authentication offered by ContainerProxy besides LDAP, OIDC and Keycloak is so-called social authentication. This type of authentication allows users to log in with

  • Facebook,
  • Twitter,
  • Google,
  • Github or
  • Linkedin

accounts into ContainerProxy.

Social authentication can be configured using

proxy:

  [...]

  authentication: social

in the application.yml file. The details related to the application identifiers and secrets for each of the social platforms can be configured in a separate social block:

proxy:

[...]

  social:
    facebook:
      app-id: yourfacebookappid
      app-secret: yourfacebookappsecret
    twitter:
      app-id: yourtwitterappid
      app-secret: yourtwitterappsecret
    google:
      app-id: yourgoogleappid
      app-secret: yourgoogleappsecret
    github:
      app-id: yourgithubappid
      app-secret: yourgithubappsecret
    linkedin:
      app-id: yourlinkedinappid
      app-secret: yourlinkedinappsecret

Since no authorization is offered by the social platforms, authorization logic is not implemented and authenticated users will be able to access all public applications.

Note:

  • the user name of the authenticated user is made available to the Shiny application via the environment variable SHINYPROXY_USERNAME.

Simple Authentication

Besides LDAP, Keycloak, OIDC and social authentication, ContainerProxy also offers the possibility to define users and groups inside the application.yml file. In order to select this authentication method, one needs to choose the simple authentication method:

proxy:

  [...]

  authentication: simple

The example configuration demonstrates how users and groups can be specified:

proxy:
  users:
  - name: jack
    password: password
    groups: scientists
  - name: jeff
    password: password
    groups: mathematicians

Since passwords are contained in clear text in the application.yml file, this is not a secure way to set up authentication, but can be useful for demonstration purposes (e.g. in the absence of a network connection) or for very specific use cases.

No authentication

In some scenarios, one wants to disable the ContainerProxy authentication. This can be done using

proxy:

  [...]

  authentication: none