This paper describes how  to leverage  Keycloak/RH-SSO in a microservice SAAS Architecture.

1) SAAS: Software as a Service with KeyCloak
  • All Saas Applications are registered within keycloak as client service using confidential mode.
  • A Saas application can be registered using client_id/client secret or client_id/signed jwt
2) Multitenancy architecture with Saas application

  • A Saas architecture is able to deal with multiple tenant.
  • A tenant corresponds to domain such as foo1.com (for compagny foo1), foo2.com (for compagny foo2) … foo.com (for compagny foon)

One of the key concept of multitenancy architecture is the concept of complete isolation from one tenant to the other.

With keycloak, this concept is leveraged using a realm per tenant basis. It means that there will be a specific realm per tenant

3) How keycloak address concept multi tenancy with Saas

Multi Tenancy, in our context, means that a single target application (WAR) can be secured with multiple Keycloak realms.

In practice, this means that the application needs to have multiple keycloak.json adapter configuration files (one per realm). Keycloak is implementing a config resolver path to detect from which tenant it has been called

org.keycloak.adapters.KeycloakConfigResolver. For example:

package example;

import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;

public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {

@Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
if (path.startsWith("alternative")) {
KeycloakDeployment deployment = cache.get(realm);
if (null == deployment) {
InputStream is = getClass().getResourceAsStream("/tenant1-keycloak.json");
return KeycloakDeploymentBuilder.build(is);
}
} else {
InputStream is = getClass().getResourceAsStream("/default-keycloak.json");
return KeycloakDeploymentBuilder.build(is);
}
}

}

 

As a consequence, it means that the Sass application needs to be registered within all tenants (i.e realms,  using and sharing same client_id/client_secret or client_id/signed jwt) for all tenants

Further information on this section are available at:

5) LDAP Identity Store – Keycloak

It is possible to use a single LDAP identity store.
At LDAP level, each tenant is going to be mapped in a different organizational unit

Example

Top level=dc=example,dc=dcom

Tenant 1: ou=foo1,dc=example,dc=com
Tenant 2: ou=foo2,dc=example,dc=com
.......
Tenant n: ou=foon,dc=example,dc=com

 

As all the different tenants are mapped on different ou branches, it is possible to have a single LDAP backend (which is containing all the different branches suffixes)

Each realm teant is mapped on a specific branch, as the tenant filtering is specified in the realm/tenant mapping

(example filter ou=foo1 for realm 1)

The LDAP database is able to achieve scalability with million of entries.

6) Integrating Saas with other IDP Providers

It is also possible to integrate with other IDP providers such as OKTA, OneLogin using SAML or opendid protocol. In this case keycloak is considered as a Service Provider (SP).

Most often, mappers have to be set in order to retrieve the mandatory attributes expzcted by keycloak such as username/email/firtsname/lastname

Accoung linking has also to be specified, as there are also various ways to deal with account linking

7) Saas presentation Login Panel with external IDP

By default, when nothing is done, a specific button is added to the usual username/login page with keycloak web page. To be redirected to the specific external IDP, the customer needs to click on this specific button.

It is possible to bypass the Keycloak panel, and being redirect immediately to the external IDP from keycloak. This provides a feeling that the Saas application is direcly hosted on the external IDP, although behind the scene it is redirected through keycloak used as SP.

The configuration of this is described at:

https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html-single/server_administration_guide/index#identity_broker

12.2. Default Identity Provider
It’s possible to automatically redirect to a identity provider instead of displaying the login form. To enable this go to Authentication select the Browser flow. Then click on config for the Identity Provider Redirector authenticator. Set Default Identity Provider to the alias of the identity provider you want to automatically redirect users to.
If the configured default identity provider is not found the login form will be displayed instead.
This authenticator is also responsible for dealing with the kc_idp_hint query parameter. See client suggested identity provider section for more details.

8) Saas – High availibility

In order to provide High Availability for Saas solution you need to consider to implement

Keycloak High Availibility:

  • It is done using Keycloak being deployed in a cluster

LDAP high availibility

  • done through LDAP replication with 2 LDAP instances as well
9) Deploying a microservice architecture with a Saas Authentication service using keycloak

Keycloak scales very well with micro-service architecture Saas architecture.
As already presented before, the user needs to have a dedicated service to perform authentication which is shared among all the different tenants.

9.1) Registering a microservice

Each microservice needs to registered with keycloak as an openID client the mode bearer only mode within keycloak

9.2) Accessing to the microservice from a client application directly

A client application for which is returned an id_token and access token, can access to the microservice directly using the access token. (It is assumed that the service client application has been configured to return access tokens and id_tokens)

This dedicated service is registered with keycloak as an openID client. It means that in response is returned a signed JWT id_token and access_token.

9.3 Passing a bearer token to a microservice

A beraer token to access the microservice can be done as follows
(customer-portal – keycloak examples)

HttpGet get = new HttpGet(UriUtils.getOrigin(req.getRequestURL().toString()) + "/database/customers");
            get.addHeader("Authorization", "Bearer " + session.getTokenString());
            try {
                HttpResponse response = client.execute(get);
                if (response.getStatusLine().getStatusCode() != 200) {
                    throw new Failure(response.getStatusLine().getStatusCode());
                }

 

9.4 Microservice verifying the signature

The id_token with keycloak is always signed with RSA256 realm signature.
This id_token is thus passed to the different microservices, where each microservice can validate that the token is valid.

As within keycloak, access tokens are also implemented as signed JWT. It is also possible to validate directly the signature of the access_token passed to the microservice.

For this, the microservice is getting hold of the public key of the realm to verify the access token.

An example of java code source verification is provided at:
https://gist.github.com/thomasdarimont/52152ed68486c65b50a04fcf7bd9bbde

 

 

 

janua
Les derniers articles par janua (tout voir)