5. How-to connect to external IAM#
Important
This section describes a how-to that involves software that’s not yet released as product by Univention.
To use the connector anyway, contact Univention GmbH directly.
This how-to outlines the general steps to connect external IAM systems and single sign-on through the protocols SAML and OpenID Connect to Univention Nubus and for the use in openDesk.
For your understanding, this how-to uses the following definitions:
- Source IAM system
is the external IAM system. Nubus can use it as source for user account objects, user group objects, and as identity provider for sign-in.
- Target
The target is the Identity Provider component in Univention Nubus.
The connection uses the following processes:
- Provisioning
During provisioning, the connector reads user account objects and user group objects through LDAP from the source and the target, calculates the differences and adds them to the target using a HTTP REST API from the Identity Provider in Univention Nubus.
- Single sign-on
For single sign-on, Nubus uses the external IAM system as SAML Identity Provider or as OpenID Connect Relying Party. The Identity Provider from Univention Nubus becomes a client to the external IAM system.
5.1. Requirements#
Before you begin, you need fulfill the following requirements:
The source must provide access to user account objects and user group objects through LDAP.
The source must provide an identity provider that supports the protocols SAML or OpenID Connect.
You have a running instance of Univention Nubus. For installation, see Installation.
For the synchronization of user accounts and user groups between the source and the target you need the UDM Directory Connector.
5.2. Setup authentication with UDM HTTP REST API#
Warning
This section can’t yet provide the needed details for the UDM HTTP REST API regarding Univention Nubus, because some pieces are still under development.
First, you need to authenticate with the UDM HTTP REST API. For authentication with the UDM HTTP REST API, follow the steps outlined in Authentication.
If you need a separate user group for authentication with the UDM HTTP REST API, you need to create the user group and add members.
Finally, you need to announce the group to the UDM HTTP REST API through the Helm Chart.
Warning
The Helm Chart for the UDM HTTP REST API doesn’t yet contain parameters for customized authentication.
You can reach the UDM HTTP REST API through the URL https://FQDN/univention/udm/schema
.
Note
Adding the group for access to the UDM HTTP REST API only grants permission for the API access. Permissions for reading and writing in OpenLDAP based on the API access need dedicated ACLs.
See also
- UDM HTTP REST API
for more information about how to use the UDM HTTP REST API.
5.3. Setup UDM Directory Connector#
Important
The UDM Directory Connector isn’t an official Univention product yet. The repository isn’t publicly available.
UDM Directory Connector is a service, that searches for user account objects and user group objects in the source and the target through LDAP. It synchronizes the found objects to the Directory Manager in Nubus through the UDM HTTP REST API.
UDM Directory Connector reads both source and target and determines the differences as a basis for the modification. The connector doesn’t store local states. It enables synchronization with targets by configuring multiple connector instances with individual configuration.
The synchronization process writes the complete OU structure of the source
to a dedicated OU in the target.
The connector uses a preconfigured UDM property as primary key, univentionObjectIdentifier
, in the target system
to identify user objects and user group objects.
Note
Renaming a group, that references a nested group, may require two runs of UDM Directory Connector to update the entries on the target system.
5.3.1. Requirements for UDM Directory Connector#
Before you setup the UDM Directory Connector, you need to fulfill the following requirements:
- Service accounts
In the source system you need a service account with the permission to search and read all user objects and user group objects.
In Univention Nubus you need a service account with the permission to write user objects and user group objects to the respective OU.
- Network
The UDM Directory Connector:
must reach the UDM HTTP REST API in the Directory Manager component in Univention Nubus on port
443/tcp
.must reach the source system on port
636/tcp
. The port depends on the source system.doesn’t need inbound connections.
- Encrypted connections with TLS
The UDM Directory connector sends clear text passwords. You need to ensure that all source and target systems have properly configured encrypted connections through TLS.
5.3.2. Installation of UDM Directory Connector#
Important
The UDM Directory Connector isn’t yet available as a container image and doesn’t yet provide a Helm Chart for convenient installation in a Kubernetes cluster.
The UDM Directory Connector is available as Python package. You can install it with pip from the Git repository. To use UDM Directory Connector in Univention Nubus, you need to create a container and deploy it to your Kubernetes cluster in the same namespace as Univention Nubus.
See also
- Git Repository for UDM Connector
for more information about the connector. The repository is only available internally to Univention GmbH.
5.3.3. Configuration of UDM Directory Connector#
For the configuration of the UDM Directory Connector you use a text file in YAML format. At the top-level hierarchy it has the following configuration dictionaries:
udm
:Configuration parameters that define the connection to UDM
source
:Configuration parameters that define the connection to the source and rules for transformation.
5.3.3.1. Example configuration#
Listing 5.1 shows a configuration example.
You can also download it from ad-domain-example.yml
.
---
# Configuration example for syncing from a typical MS AD domain controller
# the name 'ad-domain-example' is used for various parameters
udm:
uri: "https://ucs-master.example.com/univention/udm/"
user: "Administrator"
password: "supersecret"
ca_cert: "/etc/ssl/certs/ca-certificates.crt"
skip_writes: false
# FIX ME! Use more suitable attributes for storing primary keys
user_ou: "ou=ad-domain-example"
user_pkey_property: "univentionObjectIdentifier"
group_ou: "ou=ad-domain-example"
group_pkey_property: "univentionObjectIdentifier"
source:
ldap_uri: "ldaps://dc1.ad-domain.example.com"
bind_dn: "CN=Administrator,CN=Users,DC=ad-domain,DC=example,DC=com"
bind_pw: "supersecret"
ca_cert: "/etc/ssl/certs/ca-certificates.crt"
timeout: 5
search_pagesize: 500
# search paramaters for groups
group_base: "OU=UCS-Users,DC=ad-domain,DC=example,DC=com"
group_scope: "sub"
#group_filter: "(&(objectClass=group)(!(|(isCriticalSystemObject=TRUE)(cn=Domain *)(cn=* Controllers))))"
# search paramaters for users
user_base: "OU=UCS-Users,DC=ad-domain,DC=example,DC=com"
user_scope: "sub"
user_filter: "(&(objectClass=user)(sAMAccountType=805306368)(givenName=*)(sn=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
user_attrs:
- "objectGUID"
- "sAMAccountName"
- "givenName"
- "description"
- "sn"
- "ou"
- "o"
- "street"
- "l"
- "postalCode"
- "st"
- "c"
- "telephoneNumber"
- "mobile"
- "employeeNumber"
- "employeeType"
- "proxyAddresses"
user_trans:
# function sequences to sanitize input values
sanitizer:
objectGUID:
- udm_directory_connector.sanitize:guid2uuid
telephoneNumber:
- udm_directory_connector.sanitize:phone_sanitizer
mobile:
- udm_directory_connector.sanitize:phone_sanitizer
mobileTelephoneNumber:
- udm_directory_connector.sanitize:phone_sanitizer
homePhone:
- udm_directory_connector.sanitize:phone_sanitizer
homeTelephoneNumber:
- udm_directory_connector.sanitize:phone_sanitizer
facsimileTelephoneNumber:
- udm_directory_connector.sanitize:phone_sanitizer
fax:
- udm_directory_connector.sanitize:phone_sanitizer
mail:
- udm_directory_connector.sanitize:mail_sanitizer
- bytes.lower
mailPrimaryAddress:
- udm_directory_connector.sanitize:mail_sanitizer
- bytes.lower
mailLocalAddress:
- udm_directory_connector.sanitize:mail_sanitizer
- bytes.lower
mailAlternativeAddress:
- udm_directory_connector.sanitize:mail_sanitizer
- bytes.lower
# attributes to be renamed (dict-key is UDM property name)
rename_attrs:
# the primary key property <- attribute mapping
univentionSourceIdentifier: "objectGUID"
# the e-mail address for contact addressbooks (mailbox not managed by UCS)
"e-mail": "mail"
username: "sAMAccountName"
firstname: "givenName"
lastname: "sn"
mobileTelephoneNumber: "mobile"
organisation: "o"
phone: "telephoneNumber"
city: "l"
country: "c"
postcode: "postalCode"
# attributes set to a fixed attribute value list no matter what
# typically those are not mentioned in search_attrs
#fixed_attrs:
# primaryGroup:
# - "cn=Domain Users,cn=groups,dc=ucs-4,dc=local"
# single-valued(!) attributes which will be composed from other attributes no matter what
# the 1st attr value of referenced attrs is used
# composing stops at first completed variant (no KeyError)
# Note: Composed attributes must not depend on each other!
#compose_attrs:
# # the primary e-mail address for a mailbox managed by UCS (e.g. for OX)
# mailPrimaryAddress:
# - "{e-mail}"
# List of attributes to be removed after compose pass
remove_attrs:
- "objectGUID"
- "objectSid"
- "proxyAddresses"
# mapping defined per attribute type for deleting certain attribute values
remove_values:
telephoneNumber:
- "+49"
- "+49 ???"
- "0"
# mapping defined per attribute type for efficiently replacing certain attribute values
replace_values:
c:
"Deutschland": "DE"
"Bundesrepublik Deutschland": "DE"
"Frankreich": "FR"
# decompose attribute values into potentially multiple other attributes
# by using name-based regex matching
# first regex-match terminates processing!
decompose_attrs:
proxyAddresses:
- "^SMTP:(?P<mail>.+)$"
- "^smtp:(?P<mailAlternativeAddress>.+)$"
group_trans:
# attributes to be renamed
rename_attrs:
# the primary key property <- attribute mapping
univentionSourceIdentifier: "objectGUID"
name: "cn"
users: "member"
# List of attributes to be removed after compose pass
remove_attrs:
- "objectGUID"
- "objectSid"
5.3.3.2. Configuration reference#
udm
uri
:URI including base path for accessing UDM HTTP REST API.
user
:Username used for authenticating to UDM.
password
:User password used for authenticating to UDM.
ca_cert
:optional: Path of the trusted CA certificate bundle file. Defaults to your platform-specific CA bundle file.
skip_writes
:optional: If
true
, skip write operations to UDM. Default:false
.connect_timeout
:optional: Timeout in seconds to wait for connection to UDM. Default:
6.0
seconds.read_timeout
:optional: Timeout in seconds to wait for UDM results. Default:
1800
seconds.user_ou
:Name of the OU used as target container for user entries.
user_pkey_property
:optional: UDM property to use for storing the remote primary key for users.
user_properties
:optional: List of user property names the connector writes to.
group_ou
:Name of the OU used as target container for group entries.
group_pkey_property
:optional: UDM property to use for storing the remote primary key for groups.
group_properties
:optional: List of group property names the connector writes to.
source
ldap_uri
:LDAP URI of the source directory to connect to. Configure an URI starting with
ldaps://
to ensure that the connector uses LDAP over TLS right from the beginning.bind_dn
:The bind DN to use authenticate to the source directory through LDAP simple bind operation.
bind_pw
:The clear-text password to use with LDAP simple bind operation.
ca_cert
:optional: Path of the trusted CA certificate bundle file. Defaults to your platform-specific CA bundle file.
timeout
:optional: Timeout in seconds to wait for network. Default:
5
seconds.search_pagesize
:optional: Page size to used when searching with
_Simple Paged Results_
control.user_base
:search base used when searching user entries.
user_scope
:Search scope used when searching user entries. Default:
"sub"
. Possible values:"one"
,"sub"
.user_filter
:optional: LDAP filter used when searching user entries.
user_attrs
:optional: Request LDAP attributes while searching for users. Recommendation: only list the attributes actually used in the transformation and mapping later.
user_range_attrs
:optional: LDAP user attributes for which values are optionally retrieved by
_Range Retrieval_
for Microsoft Active Directory.user_trans
:Data transformation configuration applied to user entries.
group_base
:search base used when searching group entries.
group_scope
:Search scope used when searching group entries. Default:
"sub"
. Possible values:"one"
,"sub"
.group_filter
:optional: LDAP filter used when searching group entries.
group_attrs
:optional: Request LDAP attributes while searching for groups. Recommendation: only list the attributes actually used in the transformation and mapping later.
group_range_attrs
:optional: LDAP group attributes for which values are optionally retrieved by
_Range Retrieval_
for Microsoft Active Directory.group_trans
:Data transformation configuration applied to group entries.
Note
python-ldap uses the OpenLDAP client library libldap. And libldap implements a TLS hostname verification that strictly requires the hostname in the LDAP URI to match one of the DNS values of X.509v3 extension
_subjectAltName_
in the source directory’s TLS server certificate.
5.4. Setup single sign-on#
This section describes how to set up single sign-on between the source system as identity provider and the Identity Provider within Univention Nubus as service provider.
The Identity Provider within Nubus uses Keycloak and supports both protocols SAML and OpenID Connect. With its broker functionality, Keycloak can delegate the authentication to other identity providers. Depending on the configuration of the Identity Broker, end users can choose the identity provider in the Keycloak login dialog. Keycloak acts as a proxy service, forwarding the user’s sign-in request to the source system and translating between SAML and OpenID Connect if necessary.
For this how-to, you need to configure Keycloak as an Identity Broker to use the source system as a source for identities.
Before you start, make sure
that the external IAM system and Keycloak are communicating through port 443
.
5.4.1. Add source system to Keycloak#
To add the source system to Keycloak, use the following steps:
Sign in to the Keycloak Admin Console in Univention Nubus. Refer to Univention Keycloak app manual [2].
Go to the section Identity Provider.
Select a user-defined identity provider based on either OpenID Connect v1.0 or SAML v2.0.
Provide the information about the source system.
For OpenID Connect you need to provide the following values:
Alias
Discovery endpoint
Client ID
Client Secret
Other optional values
For SAML you need to provide the following values:
Alias
Service provider entity ID
SAML entity descriptor
Other optional values
Go to the section Authentication. Here you can configure different login flows. For the use case in this how-to, select the default flow browser.
Copy the login flow browser, provide a name and customize it to your needs.
It’s important to change the parameter Identity Provider Redirector to
Required
. The parameter enforces the redirection to the source system and end users don’t have to select the source system in the login dialog.In the step Identity Provider Redirector, click the cog wheel and select your previously created identity provider for your source system.
See also
Refer to the following resources from Keycloak Server Administration Guide [3]:
- Integrating identity providers
for the Keycloak documentation about external identity providers.
- OpenID Connect v1.0 identity providers
for the procedure to add a user-defined OpenID Connect v1.0 identity provider.
- SAML v2.0 identity providers
for the procedure to add a user-defined SAML v2.0 identity provider.
- Authentication flows
for the description of authentication flows.
Note
Make sure to select the documentation that matches the Keycloak version in Univention Nubus.
5.4.2. Add Keycloak as client to source system#
To add Keycloak as client in the source system, use the following steps:
Create a client configuration for Keycloak in the source system.
For OpenID Connect you need to provide the following values:
Client ID
Client Secret
Redirect URI
For SAML you need to provide the XML metadata from Keycloak.
Finally, you need to define the attributes that the source system forwards to Keycloak.
5.5. Verify the sign-in#
After you configured all pieces, you can sign in to Univention Nubus with credentials for user accounts from the source system.
In the browser, Keycloak redirects the end user to the login dialog of the source system. The end users signs in one-time. Further browser-based access to the same application then no longer requires an additional sign-in.