The SSO solution is composed of Keycloak, OpenLDAP and OAuth2 Proxy.
I rely on the talkingquickly articles for this installation.
Configure helm values in openldap/values-openldap.yml
.
# Default configuration for openldap as environment variables. These get injected directly in the container.
# Use the env variables from https://github.com/osixia/docker-openldap#beginner-guide
env:
LDAP_ORGANISATION: "Thomas Perelle's Demo"
LDAP_DOMAIN: "ssotest.perelle.com"
LDAP_BACKEND: "hdb"
LDAP_TLS: "true"
LDAP_TLS_ENFORCE: "false"
LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
LDAP_READONLY_USER: "true"
LDAP_READONLY_USER_USERNAME: readonly
LDAP_READONLY_USER_MASSWORD: password
# Default Passwords to use, stored as a secret. If unset, passwords are auto-generated.
# You can override these at install time with
# helm install openldap --set openldap.adminPassword=<passwd>,openldap.configPassword=<passwd>
adminPassword: password
configPassword: password
# Custom openldap configuration files used to override default settings
customLdifFiles:
0-initial-ous.ldif: |-
dn: ou=People,dc=ssotest,dc=perelle,dc=com
objectClass: organizationalUnit
ou: People
dn: ou=Group,dc=ssotest,dc=perelle,dc=com
objectClass: organizationalUnit
ou: Group
- With default values the base domain of the cluster is
dc=ssotest,dc=perelle,dc=com
. - 2
OrganizationalUnit
's will be created in the LDAP,People
andGroup
.
Install OpenLDAP
$ helm upgrade --install openldap ./charts/openldap --values ./openldap/values-openldap.yml --namespace identity --create-namespace
Release "openldap" does not exist. Installing it now.
NAME: openldap
LAST DEPLOYED: Wed May 4 09:35:59 2022
NAMESPACE: identity
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
OpenLDAP has been installed. You can access the server from within the k8s cluster using:
openldap.identity.svc.cluster.local:389
You can access the LDAP adminPassword and configPassword using:
kubectl get secret --namespace identity openldap -o jsonpath="{.data.LDAP_ADMIN_PASSWORD}" | base64 --decode; echo
kubectl get secret --namespace identity openldap -o jsonpath="{.data.LDAP_CONFIG_PASSWORD}" | base64 --decode; echo
You can access the LDAP service, from within the cluster (or with kubectl port-forward) with a command like (replace password and domain):
ldapsearch -x -H ldap://openldap.identity.svc.cluster.local:389 -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w $LDAP_ADMIN_PASSWORD
Test server health using Helm test:
helm test openldap
You can also consider installing the helm chart for phpldapadmin to manage this instance of OpenLDAP, or install Apache Directory Studio, and connect using kubectl port-forward.
Expose the LDAP locally:
kubectl port-forward --namespace identity \
$(kubectl get pods -n identity --selector='release=openldap' -o jsonpath='{.items[0].metadata.name}') \
3890:389
Test that the LDAP works using the ldapsearch
CLI:
$ ldapsearch -x -H ldap://localhost:3890 -b dc=ssotest,dc=perelle,dc=com -D "cn=admin,dc=ssotest,dc=perelle,dc=com" -w password
This return the content of our LDAP:
# extended LDIF
#
# LDAPv3
# base <dc=ssotest,dc=perelle,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# ssotest.perelle.com
dn: dc=ssotest,dc=perelle,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Thomas Perelle's Demo
dc: ssotest
# admin, ssotest.perelle.com
dn: cn=admin,dc=ssotest,dc=perelle,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9SklHbHoxbHJsRXJQS3J4cWl6ODJGeURXTzgrUnNlWnU=
# readonly, ssotest.perelle.com
dn: cn=readonly,dc=ssotest,dc=perelle,dc=com
cn: readonly
objectClass: simpleSecurityObject
objectClass: organizationalRole
userPassword:: e1NTSEF9djg3SUg5RDAySkYvOVZSQVNUdHJJZEtzSnZoQU9kZlc=
description: LDAP read only user
# People, ssotest.perelle.com
dn: ou=People,dc=ssotest,dc=perelle,dc=com
objectClass: organizationalUnit
ou: People
# Group, ssotest.perelle.com
dn: ou=Group,dc=ssotest,dc=perelle,dc=com
objectClass: organizationalUnit
ou: Group
# search result
search: 2
result: 0 Success
# numResponses: 6
# numEntries: 5
Adapt the configuration in keycloak/values-keycloak.yml
, especially the domain to be concordant with your environement and the OpenLDAP deployment.
helm repo add codecentric https://codecentric.github.io/helm-charts
helm upgrade --install keycloak codecentric/keycloak --values keycloak/values-keycloak.yml --namespace identity --create-namespace
Navigate to the DNS your configured in keycloak configuration, here is https://sso.ssotest.perelle.com
:
If it doesn't work, check if the keycloak
ingress has been processed in the logs of the nginx controller. It may be some issues arround the IngressClass.
Note that the access for Keycloak management is separated from the access as a service user.
You can logging in into the administration console using the account you configured in keycloack/values-keycloak.yml.
Additionnal Sources:
We are going to setup the federation between Keycloak and OpenLDAP.
In this example, we imagine that the users lifecycle in the company is managed by a dedicated team. Our SSO solution relies on this referential for identities.
Connect as admin in the administration console and create a new realm call Business
. It's always a good thing to seperate administration and business usages.
Then go in User federation
.
Then setup the ldap
federation according your OpenLDAP configuration.
Use Test connection
and Test authentication
buttons to check if the federation is working.
Save federation settings and enter the Mappers
tab of the ldap
federation.
Click the Create
button to create the group
mappers of type group-ldap-mapper
as described bellow:
Create a new user in the Business
realm.
Switch on the Email verified
button.
Use ldapsearch to check if this new user has been well created in the LDAP:
# Forward the OpenLDAP port locally
kubectl port-forward --namespace identity \
$(kubectl get pods -n identity --selector='release=openldap' -o jsonpath='{.items[0].metadata.name}') \
3890:389
# Query to check if the new user exists
$ ldapsearch -x -H ldap://localhost:3890 -b dc=ssotest,dc=perelle,dc=com -D "cn=admin,dc=ssotest,dc=perelle,dc=com" -w password
[...]
# thomas, People, ssotest.perelle.com
dn: uid=thomas,ou=People,dc=ssotest,dc=perelle,dc=com
uid: thomas
objectClass: inetOrgPerson
objectClass: organizationalPerson
mail: thomas@perelle.com
sn: perelle
cn: thomas
[...]
Now create a new team
group from the left menu, always in the Business
realm.
From the Users
menu, select the new created user and add it in the team
group.
Re-run the ldapsearch command and see that the new group is also synchronized:
[...]
# team, Group, ssotest.perelle.com
dn: cn=team,ou=Group,dc=ssotest,dc=perelle,dc=com
objectClass: groupOfUniqueNames
uniqueMember: cn=empty-membership-placeholder
uniqueMember: uid=thomas,ou=People,dc=ssotest,dc=perelle,dc=com
cn: team
[...]
Some products or applications integrate natively the capability to configure OAuth2 provider. For the others, we can use OAuth2 Proxy to secure the application at the edge with ingress annotations.
Installation
Create a new client application oauth2-proxy
in Keycloak:
Save and go to the Credentials
tab to note the associated secret.
In the Mappers
tab, create a new Groups
:
Now we can prepare the deployment of OAuth2 Proxy configuring the value file oauth2-proxy/values-oauth2-proxy.yml
, mainly clientID
, clientSecret
, cookieSecret
and the DNS.
Then deploy OAuth2 Proxy with the embedded chart:
helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests
helm upgrade --install oauth2-proxy oauth2-proxy/oauth2-proxy --values oauth2-proxy/values-oauth2-proxy.yml --namespace identity --create-namespace
We get the Sign in with Keycloak
option when we access to OAuth2 Proxy ingress domain at https://oauth.ssotest.perelle.com
The SSO solution is up and running.
- Keycloack welcome page: https://sso.ssotest.perelle.com/
- Keycloack Administration console: https://sso.ssotest.perelle.com/auth/admin/master/console
- User login page for each realm:
All this done, you can deploy applications secured by SSO.