Using GitHub and LinkedIn as identity providers for SUSE Manager single sign-on
The following article has been contributed by Bo Jin, Systems Engineer at SUSE and Linux Consultant.
Introduction
“SUSE Manager 4.1 and Uyuni (the upstream version of SUSE Manager) support single sign-on (SSO) by implementing the Security Assertion Markup Language (SAML) 2 protocol”.
This sentence means that SUSE Manager is supporting single sign-on with an Identity Provider (IdP) who acts as an identity broker. This sounds highly sophisticated – and indeed it is.
The IdP in question needs to “speak” SAML 2.0 protocol, as SUSE Manager does.
In other words, the user authentication job is being “outsourced” to “somebody else”, and the “outsourcer” (IdP), upon successful user authentication, is providing a valid token with User-ID to SUSE Manager. SUSE Manager in turn receives the token and the incoming User-ID, tries to map the incoming User-ID with an existing account in SUSE Manager, and if this is successful, finally lets the user in.
The “outsourcer” is very flexible and is able to “talk” to many other identity & authentication providers who also speak SAML 2.0 or OpenID Connect (OIDC) protocols. Those various “external” identity providers will be requested to authenticate the user. If the authentication is successful, a valid token will be generated for the user’s session and further passed to the service the user intends to consume – in our case the SUSE Manager Web UI.
Identity Brokering, Social Login and User Federation are the terms we are dealing with.
With the open source tool Keycloak as IdP, I’ve integrated single sign-on via “social login” by authenticating users with their GitHub or LinkedIn accounts to log in to the SUSE Manager Web UI. IdP-initiated authorization is supported, too (where the user starts from the IdP and gets then redirected to SUSE Manager from a catalog of apps).
Prerequisites
- SUSE Manager 4.1.x or Uyuni (the upstream version of SUSE Manager)
- Second VM with SLES15.x to run Keycloak in a container
- podman installed on the second VM to start the Keycloak container
- podman host needs to have Internet access in order to reach out to GitHub and LinkedIn
- GitHub account (a free one is sufficient)
- LinkedIn account plus having an administrator of the used organization who can verify the “verification URL” of the LinkedIn application you will be creating
Run Keycloak with podman container
Run the command:
$ podman run -p 8080:8080/tcp -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:12.0.2
Of course I would encourage everybody to use openSUSE or SUSE Linux Enterprise container image. Therefore I created an openSUSE Tumbleweed container image that can be pulled.
The Keycloak version in my openSUSE-based container image is 12.0.2:
$ podman run -p 8080:8080/tcp -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin docker.io/jinbo01/keycloak-opensuse:1.0
The repository for building the container image can be found here: https://github.com/bjin01/keycloak-test/blob/main/Dockerfile
Alternatively, you can use docker:
# docker run -td --name=idp -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin docker.io/jinbo01/keycloak-opensuse:1.0
As mentioned before, the purpose of this article is to show how to integrate GitHub and LinkedIn as identity providers and allow users to log in from these sources to the SUSE Manager Web UI.
Step-by-step guide
Configuration on Keycloak:
After you started Keycloak in the container, open your Web browser and go to http://your-host-ip-address:8080/.
Click “Administration Console” and log in with the user name and password you predefined as environment variables in the command line when you started the container.
After login create a new “REALM” and name it as you like. In my example I call it “SUMA”.
Configuration on SUSE Manager 4.x:
In the /etc/rhn/rhn.conf
file, you need to set the parameters below in order to get saml2 working.
More parameters can be found in /usr/share/rhn/config-defaults/rhn_java_sso.conf
sumahub.bo2go.home is the FQDN of the SUSE Manager host.
If you set java.sso = false
, then the SUSE Manager login works as usual without single sign-on redirection. That means you could turn off SSO with this parameter if you want to revert back to normal login.
# Single Sign-On configuration ###############
java.sso = true
java.sso.onelogin.saml2.sp.entityid = https://sumahub.bo2go.home/rhn/manager/sso/metadata
java.sso.onelogin.saml2.sp.assertion_consumer_service.url = https://sumahub.bo2go.home/rhn/manager/sso/acs
java.sso.onelogin.saml2.sp.single_logout_service.url = https://sumahub.bo2go.home/rhn/manager/sso/sls
# Identifier of the IdP entity (must be a URI)
java.sso.onelogin.saml2.idp.entityid = http://192.168.122.231:8080/auth/realms/SUMA
java.sso.onelogin.saml2.idp.single_sign_on_service.url = http://192.168.122.231:8080/auth/realms/SUMA/protocol/saml
java.sso.onelogin.saml2.idp.single_logout_service.url = http://192.168.122.231:8080/auth/realms/SUMA/protocol/saml
# Public x509 certificate of the IdP
java.sso.onelogin.saml2.idp.x509cert = MIIClzCCAX8CBgFxG1PhszANBgk.....
The Service Provider (SP) in our case is SUSE Manager. The identity provider (IdP) from the SUSE Manager point of view is Keycloak, which runs in a VM in a container.
The parameter java.sso.onelogin.saml2.idp.x509cert
needs to have the certificate of the IdP’s realm. This certificate can be found at http://192.168.122.231:8080/auth/realms/SUMA/protocol/saml/descriptor – as our realm’s name is ‘SUMA’.
All other SSO-related parameters are predefined in the /usr/share/rhn/config-defaults/rhn_java_sso.conf
file. This file comes with the SUSE Manager packages. Every parameter you want to override needs to be placed in the /etc/rhn/rhn.conf
file.
Now you can create SUSE Manager as a client in Keycloak.
Enter the service provider entity ID from the rhn.conf
file as “Client ID”. Then select saml as “Client Protocol”:
Make sure you enabled the flags and fields as shown below.
“Consent Required” is an optional parameter – this option asks if a user really wants to grant access to the service.
The parameter “Sign Assertions” = ON is mandatory.
The parameter “Signature Algorithm” = RSA_SHA1 is mandatory.
Attention:
It is important to enter the correct values for “Root URL” and “Valid Redirect URIs” which point to your SUSE Manager as shown below.
The parameter “Client Signature Required” must be OFF.
The parameter “Encrypt Assertions” must be OFF.
Ensure that you entered the assertion consumer binding URL and the logout binding URL correctly under “Fine Grain SAML Endpoint Configuration”. The URL can be taken from the rhn.conf
file paragraph as documented in the upper part of this article.
After the client is saved and created, we need to create a mapping of “which Keycloak internal user parameter” should be passed over to SUSE Manager as UID. We need to map the attribute “uid” which is expected by SUSE Manager with an attribute from the user properties within Keycloak. I decided to use “username” from the user property to map to “uid” that will be passed via saml2 to SUSE Manager.
Remove any default client scopes which could cause “duplicate attribute” problems.
Take a breath now. We just created our Service Provider (SUSE Manager) as client in Keycloak.
The next steps are to integrate GitHub and LinkedIn as external identity providers.
GitHub as Identity Provider
Start with the integration of GitHub. Open your GitHub account and go to → settings → developer settings → OAuth Apps → create a new app.
Go back to GitHub OAuth app and enter the correct “Homepage URL” and “Authorization callback URL” as shown below.
With that, you are done with GitHub so far. Let’s move on to integrate LinkedIn.
LinkedIn as Identity Provider
The following provides a sample configuration of LinkedIn as Identity provider:
First, go to https://www.linkedin.com/developers/ and log in to your existing LinkedIn account.
Create an App:
Next, you have to generate the “Verification URL” for the organization you chose during the app creation. Let the administrator of the organization verify the URL. The administrator needs to enter this URL into the browser while being logged in to the respective organization in LinkedIn.
Now copy the Application credentials to the Keycloak identity provider configuration (LinkedIn) as “Client ID” and “Client Secret”.
Go back to your LinkedIn app and enter the authorized redirect URL of the identity provider Redirect URI. This step is very important. Make sure the FQDN or IP you used is the same as you entered in the /etc/rhn/rhn.conf
file.
Attention:
It can lead to an error if you used IP for the Redirect URL in LinkedIn, but in the rhn.conf
file you used FQDN to point to your Keycloak host.
For example:
http://192.168.122.231:8080/auth/realms/SUMA/
http://mykeycloak.example.com:8080/auth/realms/SUMA/
Both URL would reach the Keycloak instance, but with regard to the redirection, this difference would cause an error by not matching the Redirect URI.
Now there is another important configuration that needs to be accomplished. The OAuth 2.0 scopes in your LinkedIn app need to be “activated”.
The default scope would allow the value r_emailaddress to be sent to external parties. In other words, the email address value of your LinkedIn account will be passed over to Keykloak. Keycloak will use the user’s email address and create a user with username = email. We remember the mapper of “username” ↔ “uid” we created within “Client”. The value of username of the user property in Keycloak will be further mapped as UID and sent to the “Client” SUSE Manager.
Thus SUSE Manager needs to have the email address as user’s ID predefined for those users coming from LinkedIn.
For privacy and security reasons I erased my test user’s email address from the below screenshot.
The question now is how to get the LinkedIn default OAuth2 scopes enabled. Under the TAB “Products” of your app definition, select the listed product “Sign in with LinkedIn”. If your organization URI has been verified, the default scope will be enabled after few minutes.
The enabled default scope parameters will be shown as below in your app – auth TAB.
One more time let’s have a look at the mapping of the fields:
The “user property” consists of a number of fields. As shown below, the “Username” is the field/parameter we used to map with the expected “uid” for SUSE Manager.
Now you have also successfully integrated LinkedIn!
Use case testing
Initially, no users exist within Keycloak’s realm “SUMA”.
The expected behaviour is to allow users to log in to SUSE Manager with their GitHub or LinkedIn user account.
The users must be predefined within SUSE Manager.
For our test, I created two users in SUSE Manager.
- Super-Admin: bjin01 (my GitHub user)
- Org-admin: xxx@xxxxx.com (my LinkedIn user)
Open a Web browser and enter your SUSE Manager host name or the following URL: https://192.168.122.85/rhn/manager/login
The login will be redirected to the Keycloak client login. I customized the login field “HTML Display name” as follows:
Now click the “LinkedIn” Button and log in to LinkedIn (apologies that the screenshot below is in German, but this is the default LinkedIn language I use). The screen below is asking the user to log in to LinkedIn.
After a successful login to LinkedIn, the next screen is asking the user to confirm if granting access is really ok. You might recall: this is the optional setting “Consent required” which we set during the “Client” definition.
After having confirmed with “Yes”, the user will be logged in to SUSE Manager. As you can see below, the SUSE Manager user name xxx@xxxxxx.com” is displayed in the UI.
If we now look at Keycloak → users, we find the user recently logged in via LinkedIn being created as new user in Keycloak.
The same steps need to be done for a GitHub login.
And our simple test case works as expected!
BTW – the question “Do you want to grant access ….” the user sees displayed in the “Client Consent Screen Text” is shown due to the setting “Consent Required”. You can also disable it.
Summary
The scenario is very basic, but it shows how to integrate social identity providers and allow them to log in to SUSE Manager. The main challenge is how to map all different user names, user IDs, and email addresses into SUSE Manager. Luckily the user name from GitHub and LinkedIn will be stored as user property “username” in the Keycloak user store. Due to the fact that the “username” within Keycloak can be from different “formats” (from userid to username to email_address), you have to make sure that the userid defined in SUSE Manager matches these values. But at the end it is up to you to define your policy and rules.
Of course the idea of using Keycloak should not be limited to allow users to log in to a tool via LinkedIn or GitHub. The generic idea of single sign-on is to ensure that users, who are successfully logged in to one of the service providers (for example SUSE Manager), within the same realm don’t need to log in for other applications again. Another service provider who supports SAML 2.0 is SUSE’s Rancher product – but that is another story, probably for another article.
FAQ
Q: Why is Keycloak in my example running without SSL and HTTPS?
A: This is for simplicity and testing purpose only. Keycloak of course supports https/ssl. https://www.keycloak.org/docs/6.0/server_installation/#setting-up-https-ssl
Q: Why is Keycloak running in stand-alone mode and not in high availability mode or with a load balancer?
A: All that is possible with keycloak. Standalone mode is for testing purpose only. The documentation describes HA and load balancer configurations in great details.
Related documentation
Related Articles
Oct 15th, 2024
What’s new in SUSE Edge 3.1?
Feb 21st, 2023
No comments yet