Skip to main content

Command Palette

Search for a command to run...

Techniques to Integrate Authentication and Authorization in Spring Boot Using Keycloak Admin Client and Resteasy

In modern enterprise systems, integrating secure authentication and authorization isn’t just an architectural afterthought — it’s a survival requirement. The more distributed and API-driven your system becomes, the more you need a central identit...

Published
5 min read
Techniques to Integrate Authentication and Authorization in Spring Boot Using Keycloak Admin Client and Resteasy
T

I am Tuanh.net. As of 2024, I have accumulated 8 years of experience in backend programming. I am delighted to connect and share my knowledge with everyone.

1. Introduction

1.1. Why Keycloak with Spring Boot?

Keycloak centralizes the authentication logic, reducing the burden on individual applications. It brings consistency, token-based validation, and auditable user management.

Spring Boot complements this by being highly modular and annotation-driven, allowing you to add security via small configurations rather than massive rewrites.

The integration between them typically involves:

  • Spring Security: for enforcing access control.
  • Keycloak Spring Adapter: for token verification.
  • Keycloak Admin Client + Resteasy: for programmatic interaction with Keycloak’s REST API.

The last part — the Admin Client — is where the real automation magic happens.

1.2. Architectural Overview

A simplified flow looks like this:

  1. A client (e.g., frontend or mobile) logs in via Keycloak and obtains an access token.
  2. The Spring Boot backend validates the token and authorizes access.
  3. Certain administrative actions (creating users, assigning roles, etc.) are handled by the Spring Boot backend using the Keycloak Admin Client.
  4. The Admin Client communicates with Keycloak’s REST endpoints through Resteasy, eliminating the need to manually handle low-level HTTP logic.

2. Implementation with Example

We’ll walk through setting up a Spring Boot application that uses the Keycloak Admin Client to manage users dynamically.

2.1. Dependencies

In your pom.xml, add:

<dependencies>
<dependency>
<groupid>org.keycloak</groupid>
<artifactid>keycloak-admin-client</artifactid>
<version>25.0.0</version>
</dependency>
<dependency>
<groupid>org.jboss.resteasy</groupid>
<artifactid>resteasy-client</artifactid>
<version>6.2.5.Final</version>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-security</artifactid>
</dependency>
</dependencies>

The keycloak-admin-client provides the Java binding for interacting with Keycloak’s Admin REST API, and resteasy-client acts as the HTTP layer that powers it.

2.2. Configuration

Create a configuration class that connects your Spring Boot app to Keycloak’s Admin API:

@Configuration
public class KeycloakConfig {

@Value("${keycloak.server.url}")
private String serverUrl;

@Value("${keycloak.realm}")
private String realm;

@Value("${keycloak.client.id}")
private String clientId;

@Value("${keycloak.client.secret}")
private String clientSecret;

@Bean
public Keycloak keycloak() {
return KeycloakBuilder.builder()
.serverUrl(serverUrl)
.realm("master")
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(clientId)
.clientSecret(clientSecret)
.build();
}

@Bean
public RealmResource realmResource(Keycloak keycloak) {
return keycloak.realm(realm);
}
}

Here’s what’s happening:

  • We connect using the client credentials grant, meaning our service authenticates as a trusted Keycloak client.
  • RealmResource provides direct access to user and role management methods within a realm.

2.3. Example: Programmatically Creating a User

Let’s implement a simple REST endpoint to create a user in Keycloak.

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {

private final RealmResource realmResource;

@PostMapping
public ResponseEntity<string> createUser(@RequestBody CreateUserRequest req) {
UserRepresentation user = new UserRepresentation();
user.setUsername(req.getUsername());
user.setEmail(req.getEmail());
user.setEnabled(true);

Response response = realmResource.users().create(user);
if (response.getStatus() == 201) {
return ResponseEntity.ok("User created successfully!");
} else {
return ResponseEntity.status(response.getStatus()).body("Failed to create user");
}
}
}

And the CreateUserRequest DTO:

@Data
public class CreateUserRequest {
private String username;
private String email;
}

This code calls Keycloak’s users().create() endpoint behind the scenes via Resteasy, serializing the payload to JSON and handling authentication headers automatically.

2.4. Assigning Roles

Once a user exists, you can assign them roles programmatically:

public void assignRole(String userId, String roleName) {
RoleRepresentation role = realmResource.roles().get(roleName).toRepresentation();
realmResource.users().get(userId).roles().realmLevel().add(Collections.singletonList(role));
}

This uses the realm-level role mapping API — one of Keycloak’s most powerful features.

You can also remove roles similarly with .remove(Collections.singletonList(role)).

3. Advanced Discussion

3.1. Handling Tokens and Security

In a production system, your Spring Boot app would not expose direct admin privileges. Instead, it would:

  • Store the admin client credentials securely (e.g., via Vault).
  • Use a service account for automation tasks only.
  • Restrict access to management endpoints via Spring Security annotations like:

@PreAuthorize("hasRole('ADMIN')")

You can configure Keycloak’s spring-boot-starter adapter for runtime authentication validation, ensuring users’ access tokens are verified via Keycloak’s introspection endpoint or public key.

3.2. Error Handling and Retry Logic

Since Resteasy operates over HTTP, transient network failures can happen. Implement retry logic using libraries like Resilience4j or Spring Retry, especially for createUser and assignRole actions.

Also, remember that Keycloak returns 409 Conflict when a username already exists — handle this gracefully in your application layer.

3.3. Integration with CI/CD and Microservices

In microservice ecosystems, you might have one centralized “Identity Service” built with this integration pattern. Other services (like billing or HR modules) would communicate with it through secured REST endpoints instead of calling Keycloak directly — ensuring loose coupling.

Additionally, the same configuration can be adapted for test environments by switching Keycloak realms dynamically based on Spring profiles.

4. Conclusion

The combination of Keycloak Admin Client, Resteasy, and Spring Boot transforms what used to be a tedious manual admin process into a fluid, programmable workflow. It allows secure, scalable, and automated management of users and roles — all while keeping the authentication logic externalized and auditable.

If you visualize the system, it’s a choreography: Keycloak plays the gatekeeper, Resteasy the messenger, and Spring Boot the conductor — each harmonizing security and functionality into one seamless melody.

Read more at : Techniques to Integrate Authentication and Authorization in Spring Boot Using Keycloak Admin Client and Resteasy

More from this blog

T

tuanh.net

540 posts

Are you ready to elevate your Java, OOP, Spring, and DevOps skills? Look no further!