SSO on microservices architecture. Using Keycloak. Part #1

In any large company, including X5 Retail Group, as it develops, the number of projects requiring user authentication increases. Over time, a seamless transition for users from one application to another becomes necessary, leading to the need for a unified Single-Sign-On (SSO) server. However, what do you do when identity providers like AD or others, lacking additional attributes, are already in use across various projects? This is where a class of systems known as "identity brokers" comes into play. The most functional representatives of this class include Keycloak, Gravitee Access Management, and others. The use cases can vary widely, including machine interactions, user participation, etc. The solution must support flexible and scalable functionality that can combine all requirements into one, and our company's current solution is the identity broker – Keycloak.

SSO on microservices architecture. Using Keycloak. Part #1

Keycloak is an open-source product designed for identity and access management, supported by RedHat. It serves as the backbone for the company's products utilizing SSO – RH-SSO.

Basic concepts

Before delving into solutions and approaches, it is essential to clarify terms and the sequence of processes:

SSO on microservices architecture. Using Keycloak. Part #1

Identification — this is the procedure of recognizing a subject by their identifier (in simpler terms, it's determining the name, username, or number).

Authentication — this is the procedure of authentication (users are verified using passwords, emails are verified with digital signatures, etc.)

Authorization — this is granting access to a resource (for example, to email).

Identity broker Keycloak

Keycloak — is an open-source solution for identity and access management, intended for use in information systems where microservices architectural patterns may be employed.

Keycloak offers features such as Single Sign-On (SSO), brokered identity, social login, user federation, client adapters, an admin console, and an account management console.

The basic functionality supported in Keycloak includes:

  • Single Sign-On and Single Sign-Out for web applications.
  • Support for OpenID/OAuth 2.0/SAML.
  • Identity Brokering – authentication using external OpenID Connect or SAML identity providers.
  • Social Login – support for Google, GitHub, Facebook, Twitter for user identification.
  • User Federation – synchronization of users from LDAP and Active Directory servers and other identity providers.
  • Kerberos bridge – using a Kerberos server for automatic user authentication.
  • Admin Console — for centralized management of settings and parameters through the Web.
  • Account Management Console – for self-management of user profiles.
  • Customization of the solution based on the company's branding.
  • 2FA Authentication – support for TOTP/HOTP using Google Authenticator or FreeOTP.
  • Login Flows – self-registration of users, password recovery and reset, and more.
  • Session Management – administrators can manage user sessions from a single point.
  • Token Mappers – mapping user attributes, roles, and other required attributes into tokens.
  • Flexible policy management through realm, application, and user.
  • CORS Support – client adapters have built-in CORS support.
  • Service Provider Interfaces (SPI) – a wide range of SPIs allowing configuration of various aspects of server operation: authentication flows, identity providers, protocol mappings, and more.
  • Client adapters for JavaScript applications, WildFly, JBoss EAP, Fuse, Tomcat, Jetty, Spring.
  • Support for various applications that work with OpenID Connect Relying Party library or SAML 2.0 Service Provider Library.
  • Expandable through the use of plugins.

For CI/CD processes, as well as automation of management processes in Keycloak, REST API/JAVA API can be used. Documentation is available electronically:

REST API https://www.keycloak.org/docs-api/8.0/rest-api/index.html
JAVA API https://www.keycloak.org/docs-api/8.0/javadocs/index.html

Enterprise-level identity providers (On-Premise)

Ability to authenticate users through User Federation services.

SSO on microservices architecture. Using Keycloak. Part #1

Also allows for seamless authentication – if users authenticate on workstations with Kerberos (LDAP or AD), they can be automatically authenticated on Keycloak without needing to re-enter their username and password.

For user authentication and subsequent authorization, a relational DBMS can be used, which is most applicable for development environments as it does not require lengthy setup and integration during the early stages of projects. By default, Keycloak uses an embedded DBMS for storing configurations and user data.

The list of supported DBMS is extensive and includes: MS SQL, Oracle, PostgreSQL, MariaDB, Oracle, and others. The most tested systems so far are Oracle 12C Release 1 RAC and Galera 3.12 cluster for MariaDB 10.1.19.

Identity providers — social login

It is possible to use login from social networks. To activate the ability to authenticate users, the Keycloak admin console is used. No changes to application code are required, and this functionality is available "out of the box" and can be activated at any stage of project implementation.

SSO on microservices architecture. Using Keycloak. Part #1

User authentication can use OpenID/SAML Identity providers.

Typical authorization scenarios using OAuth2 in Keycloak

Authorization Code Flow — used with server-side applications. One of the most common types of authorization grants because it is well-suited for server-side applications where the application's source code and client data are not accessible to outsiders. The process in this case is built on redirection. The application must be able to interact with a user agent, such as a web browser — receiving authorization codes redirected through the user agent.

Implicit Flow — used by mobile or web applications (applications running on the user's device).

The implicit authorization grant type is used by mobile and web applications where client confidentiality cannot be guaranteed. The implicit grant type also uses user-agent redirection, with the access token being passed to the user agent for further use within the application. This makes the token accessible to the user and other applications on the user's device. In this type of authorization grant, there is no authentication of the application’s authenticity, and the process relies on the redirect URL (previously registered with the service).

Implicit Flow does not support access token refresh tokens.

Client Credentials Grant Flow — used when an application accesses the API. This type of authorization grant is typically used for "server-to-server" interactions that need to be performed in the background without immediate user interaction. The client credentials grant allows a web service (confidential client) to use its own credentials instead of user impersonation for authentication when calling another web service. For a higher level of security, the calling service may use a certificate (instead of a shared secret) as credentials.

The OAuth2 specification is described in
RFC-6749
RFC-8252
RFC-6819

JWT token and its benefits

JWT (JSON Web Token) is an open standard (https://tools.ietf.org/html/rfc7519), which defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

According to the standard, a token consists of three parts in base-64 format, separated by dots. The first part is called the header, which includes the type of token and the name of the hash algorithm used for generating the digital signature. The second part holds the main information (user, attributes, etc.). The third part is the digital signature.

..
Never store the token in your database. Because a valid token is equivalent to a password, storing the token is like storing a password in plain text.
Access token is a token that provides its owner access to protected server resources. It usually has a short lifespan and can carry additional information, such as the IP address of the party requesting the token.

Refresh Token is a token that allows clients to request new access tokens after their expiration. These tokens are typically issued for a longer duration.

Key benefits of using it in a microservices architecture:

  • The ability to access various applications and services through a one-time authentication.
  • If some required attributes are missing in user profiles, data enrichment can be done, which can include automated and 'on-the-fly' additions.
  • There is no need to store information about active sessions; the server application only needs to verify the signature.
  • More flexible access management through additional attributes in the payload.
  • Using a token signature for the header and payload enhances the overall security of the solution.

JWT token - composition

The header by default, the header contains only the type of token and the algorithm used for encryption.

The type of token is stored in the 'typ' key. The 'typ' key is ignored in JWT. If the 'typ' key is present, its value must be JWT to indicate that this object is a JSON Web Token.

The second key 'alg' defines the algorithm used for encrypting the token. By default, it should be set to HS256. The header is encoded in base64.

{ "alg": "HS256", "typ": "JWT"}
Payload (content) stores any information that needs to be verified. Each key in the payload is known as a 'claim'. For example, an application may only allow entry by invitation (closed promo). When we want to invite someone to participate, we send them an invitation letter. It's important to verify that the email address belongs to the person accepting the invitation, so we will include this address in the payload by saving it under the 'email' key.

{ "email": "example@x5.ru" }

Keys in the payload can be arbitrary. However, there are several reserved ones:

  • iss (Issuer) - identifies the application from which the token is sent.
  • sub (Subject) — defines the subject of the token.
  • aud (Audience) – an array of case-sensitive strings or URIs that serves as a list of recipients for this token. When the receiving party gets a JWT with this key, it must check for its presence in the recipients — otherwise, it should ignore the token.
  • exp (Expiration Time) — specifies when the token expires. The JWT standard requires that tokens with expired validity be rejected in all implementations. The exp key must be a timestamp in Unix format.
  • nbf (Not Before) — this time in Unix format defines when the token will become valid.
  • iat (Issued At) — this key represents the time when the token was issued and can be used to determine the age of the JWT. The iat key must be a timestamp in Unix format.
  • jti (JWT ID) — a string that defines a unique identifier for this token, case-sensitive.

It is important to understand that the payload is not transmitted in encrypted form (although tokens can be nested and thus allow the transmission of encrypted data). Therefore, it should not contain any secret information. Like the header, the payload is encoded in base64.
Signature — when we have a header and payload, we can compute the signature.

The encoded base64: header and payload are combined into a string separated by a dot. Then this string and the secret key are fed into the encryption algorithm specified in the header (the "alg" key). The key can be any string. Longer strings are preferable, as they will take longer to crack.

{"alg":"RSA1_5","payload":"A128CBC-HS256"}

Building a fault-tolerant Keycloak cluster architecture

When using a single cluster for all projects, there are increased demands for the SSO solution. When the number of projects is small, these demands are not as noticeable across all projects; however, as the number of users and integrations increases, the requirements for availability and performance also rise.

The increase in risks of a single SSO failure raises the requirements for the solution architecture and the methods of component redundancy used, leading to a very strict SLA. As a result, projects often have their own non-redundant infrastructure during the development or early stages of solution implementation. As the project develops, it is essential to incorporate opportunities for growth and scaling. The most flexible way to build a fault-tolerant cluster is through the use of container virtualization or a hybrid approach.

To operate in Active/Active and Active/Passive cluster modes, data consistency in the relational database must be ensured—both database nodes must be synchronized and replicated across various geographically distributed data centers.

The simplest example of a fault-tolerant installation.

SSO on microservices architecture. Using Keycloak. Part #1

What advantages does the use of a unified cluster provide:

  • High availability and performance.
  • Support for operation modes: Active/Active, Active/Passive.
  • Dynamic scalability potential—when using container virtualization.
  • Centralized management and monitoring capabilities.
  • A unified approach to user identification/authentication/authorization in projects.
  • More transparent interaction between different projects without user involvement.
  • The ability to reuse JWT tokens across different projects.
  • A single point of trust.
  • Faster project launches using microservices/container virtualization (no need to set up and configure additional components).
  • Possibility of obtaining commercial support from the vendor.

What to pay attention to when planning a cluster.

DBMS

Keycloak uses a DBMS management system to store: realms, clients, users, etc.
A wide range of DBMS is supported: MS SQL, Oracle, MySQL, PostgreSQL. Keycloak comes with its own built-in relational database, which is recommended for lightly loaded environments such as development environments.

To operate in Active/Active and Active/Passive cluster modes, data consistency in the relational database must be ensured, and both nodes of the database cluster are synchronized and replicated across data centers.

Distributed cache (Infinispan)

For the proper functioning of the cluster, additional synchronization of the following cache types is required using JBoss Data Grid:

Authentication sessions — used to store data during the authentication of a specific user. Requests from this cache typically include only the browser and the Keycloak server, not the application.

Action tokens — used for scenarios where the user needs to confirm an action asynchronously (via email). For example, during the forget password flow, the actionTokens cache in Infinispan is used to track metadata about related action markers that have already been used, so it cannot be reused.

Caching and invalidation of persistent data – used for caching permanent data to avoid unnecessary database requests. When any Keycloak server updates data, all other Keycloak servers in all data centers must be informed.

Work — used solely for sending invalidation messages between cluster nodes and data centers.

User sessions — used to store data about user sessions that are valid during the user's browser session. The cache must handle HTTP requests from the end user and the application.

Brute force protection — used to track data on failed login attempts.

Load balancing

The load balancer is the single point of entry into Keycloak and must support sticky sessions.

Application servers

Are used to control the interaction between components and can be virtualized or containerized using available automation means and dynamic scaling of infrastructure automation tools. The most common deployment scenarios are in OpenShift, Kubernetes, Rancher.

This concludes the first part — the theoretical one. In the upcoming series of articles, examples of integrations with various identity providers and configuration examples will be discussed.

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster