Foreman supports delegation of authentication to external providers, and there’s documentation that explains how to use it to authenticate against a FreeIPA server. External sources of authentication also include LDAP and Active Directory.
However, there is no official support yet for Single Sign-On (SSO) using
SAML. An enhancement request
exists for SAML authentication support in Foreman. While the official support
gets implemented, here we’re going to explain how to use the delegation
mechanism to configure Single Sign-On (SSO) via Apache’s mod_auth_mellon
to
provide SAML-based authentication.
To illustrate the example we will use Keycloak as
the SAML identity provider, with the assistance of the
keycloak-httpd-client-install
tool to help us configure both Foreman and
Keycloak.
Preparation
This example builds upon some pre-requisites:
-
A working installation of Foreman at
https://foreman.example.com
. Foreman is our SAML service provider. This example was developed with Foreman 1.17 running on RHEL 7.4. -
A working installation of Keycloak at
https://sso.example.com
, which will be our SAML identity provider. This example was developed using Red Hat Single Sign-on 7.2 (a downstream productized version of Keycloak) on top of RHEL 7.4.
In the Foreman system we are going to use the
mod_auth_mellon
Apache module, and we’ll configure it with the help of the
keycloak-httpd-client-install tool
(man). The tool will
register Foreman as a client in Keycloak and will generate the initial
mod_auth_mellon
configuration files for Foreman’s Apache web server. We will
use a realm in Keycloak called Example.
First we need to install the required packages in foreman.example.com
:
yum install mod_auth_mellon keycloak-httpd-client-install
Then make sure that the systems involved have properly synchronized time using NTP. A difference of seconds between the Foreman and Keycloak’s clocks can prevent SSO to work.
Configure Foreman
We have to configure Foreman to allow delegation of user authentication to an external provider. This requires the following settings:
-
Enable external user authentication by setting
authorize_login_delegation
totrue
. -
Enable auto-creation of users from external authentication providers:
authorize_login_delegation_auth_source_user_autocreate
toExternal
. -
Set
login_delegation_logout_url
tohttps://foreman.example.com/saml2/logout?ReturnTo=https://foreman.example.com/users/extlogout
(replace the two occurrences offoreman.example.com
with your Foreman’s hostname). Without this, logging out from Foreman will not properly terminate your SSO session.
These can be set in foreman settings (/etc/foreman/settings.yaml
) or via the
web UI (Administer → Settings → Authentication).
Configure Apache mod_auth_mellon
As mentioned we will use the keycloak-httpd-client-install
tool to generate the
initial configuration for SAML authentication:
KEYCLOAK_URL=https://sso.example.com
KEYCLOAK_REALM=Example
KEYCLOAK_USER=admin
keycloak-httpd-client-install \
--app-name foreman \
--keycloak-server-url $KEYCLOAK_URL \
--keycloak-admin-username $KEYCLOAK_USER \
--keycloak-realm $KEYCLOAK_REALM \
--keycloak-admin-realm master \
--keycloak-auth-role root-admin \
--client-originate-method descriptor \
--mellon-endpoint saml2 \
-l /saml2 \
-l /users/extlogin \
--tls-verify false
Notes:
-
Do not put a / at the end of the
KEYCLOAK_URL
. -
This assumes a user with admin rights to Keycloak’s master realm. It’s also possible to run the tool with less privileges over Keycloak, although it might require a few more options and/or some manual configuration steps.
-
Production environments should avoid the
--tls-verify false
setting. This example was developed in a test environment without proper TLS certificates.
This will generate, among others, this configuration file:
# cat /etc/httpd/conf.d/foreman_mellon_keycloak_${KEYCLOAK_REALM}.conf
<Location />
MellonEnable info
MellonEndpointPath /saml2/
MellonSPMetadataFile /etc/httpd/saml2/foreman_sp_metadata.xml
MellonSPPrivateKeyFile /etc/httpd/saml2/foreman.key
MellonSPCertFile /etc/httpd/saml2/foreman.cert
MellonIdPMetadataFile /etc/httpd/saml2/foreman_keycloak_Example_idp_metadata.xml
MellonIdP IDP
</Location>
<Location /saml2>
AuthType Mellon
MellonEnable auth
Require valid-user
</Location>
<Location /users/extlogin>
AuthType Mellon
MellonEnable auth
Require valid-user
</Location>
The referenced files in /etc/httpd/saml2
are also generated by the tool, and a
new client will be registered on Keycloak under the specified realm.
Additional configuration
At this point we should already be able to use single sign on, but there are still a few items to improve.
Allowing local/internal logins
The default configuration for mod_auth_mellon
generated by the client
configuration tool assumes that all the locations in Foreman will use SAML auth
information. However, if we want to keep local (internal) user login —so we can
use an existing local administrator user, for example— we want to narrow down
the locations where mod_auth_mellon
authentication is enabled to only the
external login URL (/users/extlogin
) and the mod_auth_mellon
endpoints under
/saml2
.
Therefore, we will restrict the MellonEnable
settings to these two locations:
- auth for
/users/extlogin
- info for
/saml2
We will keep a section with Location /
to set common configuration parameters,
like certificate files that will be used in both locations.
With this configuration in place, users that want to log in using SSO will have to go to this URL:
https://foreman.example.com/users/extlogin
Users that want to log in using a local/internal user account will have to use this URL instead:
https://foreman.example.com/users/login
By default (e.g. when accessing https://foreman.example.com
) users will be
directed to the external login process (Keycloak) for authentication.
Attribute mapping
We need to tell both Keycloak and Foreman which attributes will be shared about the authenticated users and how to map them.
In Keycloak, login as a realm administrator to the Example realm, go to
Clients and select the Foreman client that was registered by the
keycloak-httpd-client-install
tool1. Then select the Mappers tab and
Create the following mappers, all of them with Mapper Type = User Property
and SAML Attribute NameFormat = Basic:
Name | Property | Friendly Name | SAML Attribute Name |
---|---|---|---|
username | username | username | username |
first\_name | firstName | First Name | givenname |
last\_name | lastName | Last Name | surname |
In addition to these maps there should already be an existing one to pass on group membership information; if it doesn’t exist, create it too:
Name | Mapper Type | Friendly Name | Group Attribute Name | Full group path |
---|---|---|---|---|
group list | username | List of groups | groups | OFF |
In the mod_auth_mellon
configuration we will pass on the SAML attributes as
environment variables so that Foreman can consume them:
MellonSetEnvNoPrefix "REMOTE_USER" username
MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" givenname
MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" surname
MellonSetEnvNoPrefix "REMOTE_USER_GROUP" groups
The groups attribute can have multiple values, and in this case Foreman
expects an env var with the number of groups (REMOTE_USER_GROUP_N
) and a
REMOTE_USER_GROUP_X
env var for each of the values, with X
starting at 1. We
can ask Mellon to provide these with this additional configuration:
MellonEnvVarsSetCount On
MellonEnvVarsIndexStart 1
Modified configuration file
The resulting mod_auth_mellon
configuration file after all the changes above
have been applied looks like this:
# cat /etc/httpd/conf.d/foreman_mellon_keycloak_${KEYCLOAK_REALM}.conf
<Location />
MellonEndpointPath /saml2/
MellonSPMetadataFile /etc/httpd/saml2/foreman_sp_metadata.xml
MellonSPPrivateKeyFile /etc/httpd/saml2/foreman.key
MellonSPCertFile /etc/httpd/saml2/foreman.cert
MellonIdPMetadataFile /etc/httpd/saml2/foreman_keycloak_Example_idp_metadata.xml
MellonIdP IDP
MellonEnvVarsSetCount On
MellonEnvVarsIndexStart 1
MellonSetEnvNoPrefix "REMOTE_USER" username
MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" givenname
MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" surname
MellonSetEnvNoPrefix "REMOTE_USER_GROUP" groups
</Location>
<Location /saml2>
MellonEnable info
</Location>
<Location /users/extlogin>
AuthType Mellon
MellonEnable auth
Require valid-user
</Location>
If we compare it with the original file that the keycloak-httpd-client-install
tool generated, the differences are:
# diff -u1bB /etc/httpd/conf.d/foreman_mellon_keycloak_${KEYCLOAK_REALM}.conf{.orig,}
--- /etc/httpd/conf.d/foreman_mellon_keycloak_Example.conf.orig 2018-06-01 11:18:08.008972176 -0400
+++ /etc/httpd/conf.d/foreman_mellon_keycloak_Example.conf 2018-06-13 06:26:44.598612347 -0400
@@ -1,3 +1,2 @@
<Location />
- MellonEnable info
MellonEndpointPath /saml2/
@@ -8,2 +7,9 @@
MellonIdP IDP
+ MellonEnvVarsIndexStart 1
+ MellonEnvVarsSetCount On
+ MellonSetEnvNoPrefix "REMOTE_USER" username
+ MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
+ MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" givenname
+ MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" surname
+ MellonSetEnvNoPrefix "REMOTE_USER_GROUP" groups
</Location>
@@ -11,5 +17,3 @@
<Location /saml2>
- AuthType Mellon
- MellonEnable auth
- Require valid-user
+ MellonEnable info
</Location>
Conclusion
Foreman has the ability to delegate authentication to external providers, and in this case it trusts Apache authentication modules to perform user authentication and pass on user details via the environment.
Apache has various modules for user authentication. Foreman officially supports
and documents the usage of mod_auth_pam
and mod_auth_kerb
. By using
mod_auth_mellon
we can easily add SAML based Single Sign-On to Foreman.
The keycloak-httpd-client-install
tool facilitates the configuration of
mod_auth_mellon
and its integration with Keycloak as a SAML identity provider.
With the help of that tool and a few changes to the automatically generated
configuration to adapt it to Foreman’s needs, adding Single Sign-On capabilities
to Foreman via SAML is simple.
Footnotes
1 which would be called
https://foreman.example.com/saml2/metadata
as created by the
keycloak-httpd-client-install
command above