Authentication backends

This plugins allows to use alternative authentication backends for Rudder: SAMLv2/OpenID Connect, LDAP/AD and radius (DEPRECATED).

Each authentication method is detailed below. Users are expected to know how an authentication system works independently from Rudder to configure it in Rudder: you will likely need authentication token, URLs, and other properties provided by your company.

Configure login form rendering

By default, the standard Rudder login form is displayed. SSO backends like OpenID Connect ones add links to the relevant SSO own login page below that Rudder login form. When you use such an authentication method, you want to hide or totaly remove Rudder own login form to avoid to confuse you user. For that, you can use the following property:

rudder.auth.displayLoginForm=show

Possible values are:

  • show [default]: show Rudder login form as usual

  • hide: hide the login form below a toggle button. This is a good option if you want to let your user only see SSO links by default, but still have access to the login form for special cases (like, typically, for emergency admin access when the SSO or network to it is down)

  • remove: completly remove Rudder login form.

For example, with an OpenID Connect service configured and the hide value chosen, your login form will be updated to look like:

oauth2 oidc login form

Configure enabled backends

By default, both authentication and authorization are handle in the rudder-users.xml file. But you may want to rely on your existing entreprise Active Directory or LDAP to take care of the authentication part.

To choose the scheme to use, either use 'file' or 'ldap' for the rudder.auth.provider parameter in configuration file: /opt/rudder/etc/rudder-web.properties.

After a change in Rudder /opt/rudder/etc/rudder-web.properties configuration file, you need to restart the web application with the command:

systemctl restart rudder-jetty

You can also use a comma separated list of authentication provider to use, like 'ldap,file' in which case each one will be tested in turned for authentication.

When set to 'ldap' or 'radius', passwords in rudder-users.xml are ignored and the authentication is delegated to the LDAP or radius server configured.

By convention, when LDAP authentication is enable, 'password' field in rudder-users.xml are set to 'LDAP'.

After a change in rudder-users.xml configuration file, you need to reload user information. This can be done with user-management plugin (either in UI or via API, see that plugin documentation for more information), or by restarting the web application with the command:

systemctl restart rudder-jetty

For example, to use first an ldap authentication, and then in case the user is not found in ldap, fall-back in file authentication, you will specify:

rudder.auth.provider=ldap,file

For example, that rudder-users.xml file will configure "admin" by file access, and "joe" by LDAP:

<authentication hash="sha512" case-sensitivity="true">
  <user name="admin" password="ab7f...b8a538dc69dd8de907ec" role="administrator" />
  <user name="joe" password="LDAP" role="administrator" />
</authentication>

Be careful to have only one rudder.auth.provider property in your file!

If an error happened in one of the authentication modules, the following in the provider sequence won’t be tried.

In case your authentication backend does not work, you can still configure the rootAccount in /opt/rudder/etc/rudder-web.properties to regain an administrator access. Once logged as an administrator, you can go to the Plugins > Authentication Backends page to check that Rudder interpreted correctly your configuration.

In particular, check that Computed list of providers entry matches your will.

LDAP / AD backend configuration

The configuration properties that need to be added in /opt/rudder/etc/rudder-web.properties file to configure the LDAP or AD authentication backend are displayed below.

For convenience, the part betweeb ---- add in rudder-web.properties ---- and ---- end of add in rudder-web.properties ---- can be directly added in your /opt/rudder/etc/rudder-web.properties file.

Note that key "rudder.auth.provider" is likelly to already exists. In that case, just update it with the sequence of authentication backend you want to try.

---- add in rudder-web.properties ----

###########################
# Rudder Authentication    #############################################################
###########################

#
# update provider:
#
rudder.auth.provider=ldap


###########################
# LDAP Authentication      #############################################################
###########################


# The following parameters allow to configure the LDAP authentication provider.
# The LDAP authentication procedure is a typical bind/search/rebind, in which
# an application connection (bind) is used to search (search) for an user entry
# given some base and filter parameters, and then, a bind (rebind) is tried on
# that entry with the credential provided by the user.
# That allows to separate the user DN (especially RDN) from the search criteria while
# in the same time supporting users located in several different organisational units.
#
# Be careful, authorizations are still done based on the content of rudder-user.xml,
# meaning that each user should have access to Rudder MUST have a line in that file.
# Without that line, the user can have a successful LDAP authentication, but
# won't be able to do or see anything in Rudder (only logout).
#

# === EXAMPLE / ldapsearch test===
#
# With the example data below, if the user "jon.doe" try to login with password "mypasswd",
# the corresponding `ldapsearch` request are:
#
# 1/ search for user with `service` login:
# ----
# $ ldapsearch -LLL -o ldif-wrap=no -h ldap.mycorp.com -p 389 -x -D "cn=rudder,ou=services,dc=mycorp,dc=com" -w secret -b "ou=Users,dc=mycorp,dc=com" -s sub '(&(cn=jon.doe)(objectclass=person))' 1.1
#
#  dn: cn=jon.doe,ou=Paris,ou=Users,dc=mycorp,dc=com
# ----
#
# Errors and unexpected:
# - an authentication error here means that your rudder service user does not have the
#   rights to do a search and will not be able to find the corresponding user full DN;
# - you should get exactly one result: the DN to use in the second request. If you don't
#   get any results, check the base DN and the LDAP filter.
#
# 2/ bind request with user DN (search user own entry with its credentials):
# ----
# $ ldapsearch -LLL -o ldif-wrap=no -h ldap.mycorp.com -p 389 -x -D "cn=jon.doe,ou=Paris,ou=Users,dc=mycorp,dc=com" -w mypasswd -b "cn=jon.doe,ou=Paris,ou=Users,dc=mycorp,dc=com" -s base 1.1
#
# dn: cn=jon.doe,ou=Paris,ou=Users,dc=mycorp,dc=com
# ----
#
# Errors and unexpected:
# - an authentication error here is likely to mean that the user password is not correct,
#   but you should also check your LDAP directory ACLs.
#

#
# Connection URL to the LDAP server, in the form:
# ldap://hostname:port/base_dn
#
rudder.auth.ldap.connection.url=ldap://ldap.mycorp.com:389/dc=mycorp,dc=com

#
# Bind DN used by Rudder to do the search. This is the "service" or
# "application" DN for Rudder in you LDAP directory, or an LDAP user with
# enought rights to be able to walk the user branch configured below.
# LDAP dn, no default value.
#
rudder.auth.ldap.connection.bind.dn=cn=rudder,ou=services,dc=mycorp,dc=com

#
# Bind password used by Rudder service (the DN configured just above) to do the search.
# String, no default value.
#
rudder.auth.ldap.connection.bind.password=secret

#
# Search base and filter to use to find the user.
# The search base can be left empty. In that
# case, the root of directory is used.
#
rudder.auth.ldap.searchbase=ou=People

#
# In the filter, {0} denotes the value provided as
# login by the user.
# The filter must lead to at most one result, which
# will be used to try the (re)bind request.
#
rudder.auth.ldap.filter=(&(uid={0})(objectclass=person))

#
# An AD example would be:
#
#rudder.auth.ldap.searchbase=
#rudder.auth.ldap.filter=(&(sAMAccountName={0})(objectclass=user))

---- end of add in rudder-web.properties ----

Using a certificate for secure connection to LDAP/AD

If you want to connect with a secure connection to an LDAP or AD, you need to add the directory certificate to Rudder’s JVM keystore.

Without that, you will see errors in /var/log/rudder/webapp/XXXXXXX_stderrout.log files like:

WARN  application - Login authentication failed for user 'xxx' from IP '127.0.0.1|X-Forwarded-For:xxx.xxx.xxx.xxx': simple bind failed: xxx.xxx:636; nested exception is javax.naming.CommunicationException: simple bind failed:

xxx.xxx:636 [Root exception is java.net.SocketException: Connection or outbound has closed]

Adding certificate to JVM keystore

# copy the certificate somewhere in /opt/rudder

cd path/to/jdk<in-use-version>/lib/security

keytool -importcert -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias "rudder-ldap-certificate" -file <path to AD server certificate>

Error because certificate is 1024 bits

Since JVM version 8, certificate of size 1024 or less are forbidden by default. If you still use a certificate with that size, you will get errors like:

Root exception is javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Algorithm constraints check failed on keysize limits: RSA 1024 bit key used with certificate

To correct that problem, you need to remove that restriction (and update your certificates for security):

  • edit path/to/jdk<in-use-version>/conf/security/java.security

  • check constraints on RSA keysize like RSA keySize < 1024 and change them to match your key size for properties:

  • jdk.tls.disabledAlgorithms

  • jdk.certpath.disabledAlgorithms

  • restart rudder-jetty

OAUTHv2 / OpenID Connect

OpenID Connect (OIDC) is a very common SSO protocol to authenticate and manage authorizations of users in a decentralized, multi-tenant set-up (ie, typically web applications nowadays). It’s built on top of OAUTHv2 and replace it in most new cases.

These protocols delegate the actual authentication to an identity provider (IdP) that in turns send the relevant authentication information to the client, i.e. to Rudder in our case. These IdP can be public providers, like Google, deployed and managed internally in a company, like ForgeRock’s open source OpenAM, or used as SaaS, like Okta - and often, providers do a mix of these things.

Rudder support plain old OAUTHv2 and OpentID Connect. They have several normalized scenario and Rudder supports the most common for a web application server side authentication: Authentication using Authorization Code Flow.

To use these providers, you need to update the rudder.auth.provider property with the oauth2 value for an OAUTHv2 identity provider, and with the oidc value for an OpenID Connect identity provider.

As always, you can have several back-ends configured for fall-back authentication. For example, to use OIDC with a fall-back to the Rudder file based authentication, use:

rudder.auth.provider = oidc, file

You can configure several providers at the same time. The are defined by an identifier in a comma-separated list in the following property:

rudder.auth.oauth2.provider.registrations=okta,google

Each provider needs to then have a bunch of properties defined for it. They are listed below and all follow the pattern rudder.auth.oauth2.provider.${providerID}.${subPath} where `providerId is the ID in the previous list, and subPath is the remaining name of the property.

In the next below description, we use okta as a provider. We chose this one because OAUTHv2/OpenID Connect configuration can be a bit complicated and full of jargon, and so having a real, well documented reference is helpful - and Okta provides that.

# Authentication provider id in rudder.auth.provider:
# - OAUTHv2       : oauth2
# - OpenID Connect: oidc

# Configure the list of Identity provider services. Here, you choose
# an identifier for each service as a comma separated list.
# Identifier should be lower case ascii, -, _. For example, if
# your company uses both "Okta" and "Google", you can choose "okta" and
# "google" (how original) identifiers:
rudder.auth.oauth2.provider.registrations=okta,google

# Now, configure Okta related properties. You will need to do
# the same for each provider with an identifier.

# The identity service provider name as it will be displayed in Rudder
rudder.auth.oauth2.provider.okta.name=Okta
# A more detailed explanation message displayed in authentication page.
rudder.auth.oauth2.provider.okta.ui.infoMessage=OpenID Connect SSO (Okta)

# In Oauth2/OIDC, a client (ie, Rudder) is identifier by a pair of credentials:
# - 1/ an id,
# - 2/ a corresponding secret key.
#
# 1/ Identifier of the application you created in your IdP for Rudder.
#    In Okta, it will be listed under https://xxxx-admin.okta.com/admin/apps/active
#    once you created it with "Create App Integration". If you click on your application,
#    it's located in "Client Credential > Client ID".
#
rudder.auth.oauth2.provider.okta.client.id=0oa3snkopsIRIIHb35d7
#
# 2/ The corresponding "client secret", provided by your Identity Provider.
#    For Okta, it's available when you click on your application in
#    https://xxxx-admin.okta.com/admin/apps/active in "Client Credential > Client Secret"
rudder.auth.oauth2.provider.okta.client.secret=-0Q5jGbdvV5WkfGNJwHfkOP0FdZ5vhqPYav7icYb
#
# Space separated list of OAUTHv2 "scope" for claims that should be included in the identity
# token once authentication is done. These values should be documented by your IdP documentation.
# Rudder only need to have at least scope which provides the attribute that will be used for
# `userId` (see next property)
rudder.auth.oauth2.provider.okta.scope=openid  email profile
#
# The attribute that will be used for `userId` and login matching with rudder users
# (generally, it's a login or email ; OIDC always provides at least `sub` attribute)
# The value of that attribute will be used to retrieved Rudder internal user, its rights, etc.
rudder.auth.oauth2.provider.okta.userNameAttributeName=email
#
# The next 4 URLs are the redirection URLs towards the IdP and which correspdonds to
# each step of the authentication process (yes, the protocol does a lot of redirection):
# - `uri.auth`: first URL, Rudder ask for a code request. User is then redirected by
#    the IdP towards its own login form. It then redirect to Rudder with a code to process.
#    If you need to use extra information like an `acr_values` property, just happen it to that URL
# - `uri.token`: Rudder returned the code processed with its client secret. The IdP process it
     and return an authentication token to Rudder.
# - `uri.userInfo`: Rudder uses the authentication token to get user information on that URL
# - `uri.jwkSet`: in the case of OIDC, the token is a signed JWT token. That last url is the
#   URL where Rudder can get the IdP public key to sign the token.
rudder.auth.oauth2.provider.okta.uri.auth=https://xxxx.okta.com/oauth2/v1/authorize
# With an acr_values:
#rudder.auth.oauth2.provider.okta.uri.auth=https://xxxx.okta.com/oauth2/v1/authorize?acr_values=strongAuthRequired
rudder.auth.oauth2.provider.okta.uri.token=https://xxxx.okta.com/oauth2/v1/token
rudder.auth.oauth2.provider.okta.uri.userInfo=https://xxxx.okta.com/oauth2/v1/userinfo
rudder.auth.oauth2.provider.okta.uri.jwkSet=https://xxxx.okta.com/oauth2/v1/keys
#
# Rudder URL towards which the identity provider redirects, ie the URL seen by the IdP
# for Rudder. Apart if directed to do differently, you should keep the
# part after `rudder`, ie: `/login/oauth2/code/{registrationId}` part.
rudder.auth.oauth2.provider.okta.client.redirect=https://my-external-rudder-hostname/rudder/login/oauth2/code/{registrationId}
#
#
# The following properties are necessary for each provider configuration but should not be modified.
#
# The protocol scheme used for authentication - Rudder only supports with authorisation code.
rudder.auth.oauth2.provider.okta.grantType=authorization_code
# Authentication type - Rudder only supports client_secret_basic and client_secret_post.
rudder.auth.oauth2.provider.okta.authMethod=client_secret_basic

Log information

OIDC and OAuth2 protocols may become complicated to configure, especially for the scopes part, when you need to match an attribute with Rudder login base. You can use the log level for auth-backends in /opt/rudder/etc/logback.xml:

  • debug to see which attributes are actually returned into the user info token,

  • and trace to also see their values.

Common Oauth2/OIDC error cases

It can be a bit challenging to understand what is not correct in a Oauth2 or OIDC configuration. Here are some guide lines to help address possible configuration problems.

I don’t see the list of Identity Provider in login form

Check that you correctly updated parameter rudder.auth.provider to include oidc or oauth2 in the list, that you have at least one key defined in rudder.auth.oauth2.provider.registrations, and that you have Rudder webapp logs (/var/log/rudder/webapp/YYYY_mm_dd.stderrout.log) lines like:

[timestamp] INFO  application - Configured authentication provider(s): [rootAdmin, oidc, file]
[timestamp] INFO  application - Add backend providers 'Oauth2 and OpenID Connect authentication backends provider: 'oauth2','oidc'
[timestamp] INFO  application.plugin - Oauthv2 or OIDC authentication backend is enabled, updating login form

I get a 404 page not found on Identity Provider

Check with your Identity Provider Manager that the URL for rudder.auth.oauth2.provider.${registrationKey}.uri.auth is correct.

I get a 400 bad request on Identity Provider

If when you click in Rudder login page to the IdP link and that you get an error 400 "bad request", the application code for Rudder is not correct, and so Rudder identity is not recognized by the IdP. Check with your IdP provider the application code for Rudder and check that that value is correctly set for property rudder.auth.oauth2.provider.${registrationKey}.client.id

After login on Identity Provider, I get a "login error" message in Rudder login page

This can have several cause and we will need to analyse Rudder log to understand what happened.

Bad token URL

In the log, you see (exact error code or ID may vary, check invalid_token_response and The endpoint does not support the provided HTTP method):

[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorization to: https://identity-provider-url/oauth2/v1/authorize
[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorisation validation and starting authentication request
[timestamp] WARN  application - Login authentication failed for user 'unknown' from IP '127.0.0.1': [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 405 Method Not Allowed: "{"errorCode":"E0000022","errorSummary":"The endpoint does not support the provided HTTP method","errorLink":"E0000022","errorId":"oaeLqoJpDbwTzOTAJhp9TbVig","errorCauses":[]}"

Check with you Identity Provider Manager the value for rudder.auth.oauth2.provider.${registrationKey}.uri.token.

Bad user info URL

In the log, you see (exact error code or ID may vary, check invalid_user_info_response and The endpoint does not support the provided HTTP method):

[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorization to: https://identity-provider-url/oauth2/v1/authorize
[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorisation validation and starting authentication request
[timestamp] WARN  application - Login authentication failed for user 'unknown' from IP '127.0.0.1': [oauth2:invalid_user_info_response] An error occurred while attempting to retrieve the UserInfo Resource: 405 Method Not Allowed: "{"errorCode":"E0000022","errorSummary":"The endpoint does not support the provided HTTP method","errorLink":"E0000022","errorId":"oae1TIF6av1QOiox05xkUSkww","errorCauses":[]}"

Bad JWK (keys) URL

In the log, you see (exact error code or ID may vary, check invalid_id_token and The endpoint does not support the provided HTTP method):

[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorization to: https://identity-provider-url/oauth2/v1/authorize
[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorisation validation and starting authentication request
[timestamp] WARN  application - Login authentication failed for user 'unknown' from IP '127.0.0.1': [invalid_id_token] An error occurred while attempting to decode the Jwt: Couldn't retrieve remote JWK set: org.springframework.web.client.HttpClientErrorException$MethodNotAllowed: 405 Method Not Allowed: "{"errorCode":"E0000022","errorSummary":"The endpoint does not support the provided HTTP method","errorLink":"E0000022","errorId":"oae6_QrhU-UTWeykOHgyHqbuA","errorCauses":[]}"

Bad application secret or method

In the log, you see:

[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorization to: https://identity-provider-url/oauth2/v1/authorize
[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorisation validation and starting authentication request
[timestamp] WARN  application - Login authentication failed for user 'unknown' from IP '127.0.0.1': [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]

This likely means that the value of rudder.auth.oauth2.provider.${registrationKey}.client.secret is incorrect. Please check with your Identity Provider manager to get the correct one.

It could also mean that your Identity Provider only support the client_secret_post authentication method. You can try to change rudder.auth.oauth2.provider.okta.authMethod to that value.

User attribute unknown

In the log, you see:

[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorization to: https://identity-provider-url/oauth2/v1/authorize
[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorisation validation and starting authentication request
[timestamp] DEBUG auth-backends - OAuth2/OIDC user info request with scopes [email openid profile] returned attributes: email, email_verified, family_name, given_name, locale, name, nickname, preferred_username, sub, updated_at, zoneinfo
[timestamp] WARN  application - Login authentication failed for user 'unknown' from IP '127.0.0.1': [oauth2:invalid_user_info_response] Missing attribute 'foo' in attributes

You used an attribute for value rudder.auth.oauth2.provider.${registrationKey}.userNameAttributeName that is not returned with the user profile. Please check rudder.auth.oauth2.provider.okta.scope with your Identity Provider Manager to ensure that the list of scope is correct, and check that the userNameAttributeName value is in the list of returned attributes.

Incorrect user attribute

In the log, you see:

[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorization to: https://identity-provider-url/oauth2/v1/authorize
[timestamp] DEBUG auth-backends - Processing OAuth2/OIDC authorisation validation and starting authentication request
[timestamp] DEBUG auth-backends - OAuth2/OIDC user info request with scopes [email openid profile] returned attributes: email, email_verified, family_name, given_name, locale, name, nickname, preferred_username, sub, updated_at, zoneinfo
[timestamp] WARN  application - Login authentication failed for user 'unknown' from IP '127.0.0.1': User with username 'foo' was not found

It means that the value used for rudder.auth.oauth2.provider.${registrationKey}.userNameAttributeName was correctly returned in the profile list for the authenticated user, but that value was not found in Rudder user configuration files /opt/rudder/etc/rudder-users.xml. Check that one of the entries in that file has the corresponding value for its name attribute.

Radius backend

Radius backend is deprecated as of Rudder 7.0. It will be removed in a next version of Rudder. You should try to replace it with another backend. In case that backend is a must-have for you, please contact Rudder company for discussing how to help you migrate away of Radius of get specific support for it.

Below follow the configuration properties that need to be added in /opt/rudder/etc/rudder-web.properties file to configure the Radius authentication backend.

For convenience, the part under "---- add in rudder-web.properties----" can be directly added in your /opt/rudder/etc/rudder-web.properties file.

Note that key rudder.auth.provider is likelly to already exists. In that case, just update it with the sequence of authentication backend you want to try.

---- add in rudder-web.properties ----

###########################
# Rudder Authentication    #############################################################
###########################

# update provider list:
rudder.auth.provider=radius

###########################
# Radius Authentication    #############################################################
###########################

#
# The following parameters allow to configure authentication with a
# Radius server.
#


#
# Use "radius" auth type to enable radius authentication
#
#rudder.auth.provider=file,radius

#
# IP or hostname of the Radius server. Both work, but it is preferred to use an IP.
#
rudder.auth.radius.host.name=192.168.42.80

#
# Authentication port for the Radius server
#
rudder.auth.radius.host.auth.port=1812

#
# The shared secret as configured in your Radius server for Rudder application / host.
#
rudder.auth.radius.host.sharedSecret=secret

#
# Time to wait in seconds when trying to connect to the server before giving up.
#
rudder.auth.radius.auth.timeout=10

#
# Number of retries to attempt in case of timeout before giving up.
#
rudder.auth.radius.auth.retries=0

#
# Authentication protocol to use to connect to the Radius server. The default
# one is 'pap' (PAP).
# Available protocols::
# - pap
# - chap
# - eap-md5
# - eap-ttls
#
# For `eap-ttls`, you can append `key=value` parameters, separated by `:` to the
# protocol name to specify protocol option, for example:
# `eap-tls:keyFile=keystore:keyPassword=mypass`
#
rudder.auth.radius.auth.protocol=pap

---- end of add in rudder-web.properties ----

← API authorizations Branding →