Authentication backends
This plugins allows to use alternative authentication backends for Rudder: SAMLv2, OpenID Connect, and LDAP or Active Directory (AD). The old radius module is deprecated and will totally removed in a future version.
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:
Configure enabled backends
Using one external backend for authentication
By default, both authentication and authorization are handle in the rudder-users.xml
file. But you may want to rely on your existing enterprise Active Directory or LDAP
to take care of the authentication part.
This behavior can be changed to use one of the provided authentication provider described
below by editing the configuration property rudder.auth.provider
in
/opt/rudder/etc/rudder-web.properties
.
For example, if you want to use the LDAP/AD authentication backend, you will set:
rudder.auth.provider=ldap
Identifier for each authentication backend is documented in its respective chapter below.
After a change in Rudder
|
When set to external provider like 'ldap', 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
|
Using several backends for authentication
You can also use a comma separated list of authentication providers in rudder.auth.provider
,
like 'ldap,file' in which case each one will be tested in turned for authentication.
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 |
If an error happened in one of the authentication modules, the following in the provider sequence won’t be tried. |
Root access when external authentication is not working
In case your authentication backend does not work, you can still configure the
In particular, check that |
LDAP / AD backend configuration
The configuration properties needed to configure the LDAP or AD authentication backend are displayed below.
You should copy the whole configuration properties in a new file under
/opt/rudder/etc/rudder-web.properties.d/
(see
xref:reference:administration:webapp.adoc#_configuration for more detail about
how Rudder configuration properties override works).
Note that key "rudder.auth.provider" is already defined in /opt/rudder/etc/rudder-web.properties
and will need to be updated in that place:
#
# update provider:
#
rudder.auth.provider=ldap
---- copy into new file /opt/rudder/etc/rudder-web.properties.d/20-ldap-authentication.properties ----
###########################
# 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 ldap authentication properties to copy ----
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
likeRSA 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.
We advise to configure each provider in it’s own configuration file under /opt/rudder/etc/rudder-web.properties.d
so that it is easier to change or disable some of them.
Example configuration for okta
provider
In this section, we use okta
as OIDC provider, and we chose the name okta
to identify that provider in Rudder configuration file.
We chose this OIDC provider because it provides freely available extensive documentation and testing platform. This can be useful since OAUTHv2/OpenID Connect configuration can be a bit complicated and full of jargon.
In the remaining part of this section, you will need to change okta
by the name you chose to identify your OIDC provider in Rudder.
You can copy the following example into /opt/rudder/etc/rudder-web.properties.d/30-oidc-okta-authentication.properties
.
# 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 →