{"id":3641,"date":"2025-12-24T10:00:56","date_gmt":"2025-12-24T15:00:56","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3641"},"modified":"2025-12-24T10:00:56","modified_gmt":"2025-12-24T15:00:56","slug":"integrating-java-spring-with-keycloak-a-comprehensive-guide","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/spng_security\/integrating-java-spring-with-keycloak-a-comprehensive-guide\/","title":{"rendered":"Integrating Java Spring with Keycloak: A Comprehensive Guide"},"content":{"rendered":"\n<div class=\"wp-block-jetpack-markdown\"><p>Java Spring, a popular framework for building enterprise-level applications, can seamlessly integrate with Keycloak, a robust open-source Identity and Access Management (IAM) solution. This combination offers a powerful way to implement secure authentication, authorization, and user management features in your Spring-based applications. Let\u2019s explore how to achieve this integration along with key functionalities.<\/p>\n<p><strong>Understanding OAuth2<\/strong><\/p>\n<p>At the heart of Keycloak\u2019s integration lies the OAuth2 protocol. This protocol enables secure authorization and delegation of access between applications. In essence, your Spring application acts as a client that requests authorization from Keycloak (the authorization server) on behalf of the user. Keycloak then issues an access token that your Spring application can use to access protected resources on behalf of the authenticated user.<\/p>\n<p><strong>Role Manager<\/strong><\/p>\n<p>Keycloak\u2019s role management system allows you to define various roles within your application and assign them to users. You can then use these roles within your Spring application to control access to different parts of your application or specific functionalities. This provides a fine-grained authorization mechanism.<\/p>\n<p><strong>MFA (Multi-Factor Authentication)<\/strong><\/p>\n<p>Keycloak supports MFA, which adds an extra layer of security to your application. Users will be required to provide additional verification, such as a code from their smartphone or a fingerprint scan, in addition to their username and password.<\/p>\n<p><strong>Email Verification and Reset<\/strong><\/p>\n<p>Keycloak provides built-in functionality for email verification and password reset. When a user registers, they receive an email with a link to verify their email address. Similarly, if they forget their password, they can request a password reset link to be sent to their registered email address.<\/p>\n<p><strong>Customizing the Login Screen<\/strong><\/p>\n<p>Keycloak offers a good degree of flexibility when it comes to tailoring the login experience to match your application\u2019s branding and design. Here\u2019s a breakdown of the steps involved:<\/p>\n<ol>\n<li>\n<p><strong>Access the Keycloak Themes:<\/strong><\/p>\n<ul>\n<li>Log in to your Keycloak Admin Console.<\/li>\n<li>Navigate to your realm.<\/li>\n<li>Go to <code>Realm Settings<\/code> -&gt; <code>Themes<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Create a New Theme or Copy an Existing One<\/strong><\/p>\n<ul>\n<li>You have two options here:\n<ul>\n<li><strong>Create a New Theme:<\/strong> Click the <code>Add Theme<\/code> button and provide a name for your new theme.<\/li>\n<li><strong>Copy an Existing Theme:<\/strong> If you want to make modifications to the default look, you can copy the <code>base<\/code> theme and then customize it.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Modify the Theme Files:<\/strong><\/p>\n<ul>\n<li>Once you\u2019ve created or copied a theme, you\u2019ll see a list of files associated with it. The most important one for login customization is <code>login\/login.ftl<\/code>.<\/li>\n<li>Download this <code>login.ftl<\/code> file.<\/li>\n<li>Open the file in a text editor or your preferred IDE.<\/li>\n<li>You\u2019ll see a mix of HTML, CSS, and FreeMarker template language constructs. This is where you can make your changes.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Key Areas for Customization<\/strong><\/p>\n<ul>\n<li><strong>HTML Structure:<\/strong> Modify the existing HTML elements or add new ones to change the layout of the login form.<\/li>\n<li><strong>CSS Styling:<\/strong> Update the CSS rules to adjust colors, fonts, spacing, and other visual aspects of the login screen.<\/li>\n<li><strong>FreeMarker:<\/strong> Use FreeMarker directives to dynamically include content or control the display of elements based on conditions.<\/li>\n<li><strong>Keycloak-Specific Classes:<\/strong> Keycloak provides some CSS classes that you can leverage to target specific elements on the login screen. Refer to the Keycloak documentation for a list of these classes.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Upload the Modified Theme:<\/strong><\/p>\n<ul>\n<li>Once you\u2019re satisfied with your changes, save the <code>login.ftl<\/code> file.<\/li>\n<li>Back in the Keycloak Admin Console, in your theme\u2019s file list, click the <code>Upload<\/code> button next to <code>login\/login.ftl<\/code>.<\/li>\n<li>Select your modified file and upload it.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>Apply the Theme to your Client<\/strong><\/p>\n<ul>\n<li>Navigate to your client\u2019s settings.<\/li>\n<li>Go to the <code>Themes<\/code> tab.<\/li>\n<li>Under <code>Login Theme<\/code>, select the name of your custom theme.<\/li>\n<li>Save the changes.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><strong>Tips for Customization<\/strong><\/p>\n<ul>\n<li><strong>Inspect Element:<\/strong> Use your browser\u2019s developer tools to inspect the elements on the default login screen. This will help you understand the existing structure and CSS classes.<\/li>\n<li><strong>Keycloak Documentation:<\/strong> Refer to the Keycloak documentation for detailed information about theming and customization options.<\/li>\n<li><strong>Version Compatibility:<\/strong> Keep in mind that the theming structure and available options might vary slightly between different Keycloak versions.<\/li>\n<li><strong>Testing:<\/strong> Thoroughly test your customized login screen across different browsers and devices to ensure it looks and functions as expected.<\/li>\n<\/ul>\n<p><strong>Advanced Customization<\/strong><\/p>\n<ul>\n<li>If you require even more extensive customization, you can explore creating custom FreeMarker templates or even developing your own custom login forms.<\/li>\n<\/ul>\n<p><strong>Spring Configuration<\/strong><\/p>\n<p>Let\u2019s delve into the essential steps to configure Keycloak in your Spring application.<\/p>\n<ol>\n<li>\n<p><strong>Add Keycloak Dependencies:<\/strong>\nInclude the necessary Keycloak dependencies in your <code>pom.xml<\/code> (for Maven) or <code>build.gradle<\/code> (for Gradle) file.<\/p>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;org.keycloak&lt;\/groupId&gt;\n    &lt;artifactId&gt;keycloak-spring-boot-starter&lt;\/artifactId&gt;\n    &lt;version&gt;x.x.x&lt;\/version&gt; &lt;\/dependency&gt;\n<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>Configure Keycloak Properties:<\/strong>\nProvide your Keycloak server details, realm name, client ID, and other relevant settings in your <code>application.properties<\/code> or <code>application.yml<\/code> file.<\/p>\n<pre><code class=\"language-yaml\">keycloak:\n  realm: your-realm-name\n  auth-server-url: http:\/\/localhost:8080\/auth\n  ssl-required: external\n  resource: your-client-id\n  public-client: true\n  bearer-only: true\n<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>Secure Endpoints:<\/strong>\nUse Spring Security annotations to protect your endpoints based on roles or other authorization criteria.<\/p>\n<pre><code class=\"language-java\">@PreAuthorize(&quot;hasRole('admin')&quot;)\n@GetMapping(&quot;\/admin&quot;)\npublic String adminPage() {\n    return &quot;Admin Page&quot;;\n}\n<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>Access User Information:<\/strong>\nRetrieve user information, including roles and attributes, from the Keycloak <code>Principal<\/code> object in your controllers.<\/p>\n<pre><code class=\"language-java\">@GetMapping(&quot;\/user&quot;)\npublic String userPage(Principal principal) {\n    KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) principal;\n    KeycloakSecurityContext keycloakSecurityContext = keycloakPrincipal.getKeycloakSecurityContext();\n    AccessToken accessToken = keycloakSecurityContext.getToken();\n    \/\/ Access user information from accessToken\n    return &quot;User Page&quot;;\n}\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>Integrating Java Spring with Keycloak offers a robust and flexible solution for implementing authentication, authorization, and user management in your applications. By leveraging OAuth2, role management, MFA, and other Keycloak features, you can enhance the security and user experience of your Spring-based applications. Remember that this blog post provides a foundational overview. Delve deeper into the official Keycloak and Spring Security documentation for more advanced configurations and customization options.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":3642,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[441],"tags":[69,319],"series":[397],"class_list":["post-3641","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spng_security","tag-java-2","tag-spring","series-spring"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/08\/ghost-7571881_1280-jpg.avif","jetpack-related-posts":[{"id":3569,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/integrating-prolog-with-spring-boot\/","url_meta":{"origin":3641,"position":0},"title":"Integrating Prolog with Spring Boot","author":"Jeffery Miller","date":"April 20, 2026","format":false,"excerpt":"Prolog, a declarative logic programming language, shines in solving specific types of problems that require knowledge representation and logical inference. Integrating Prolog with Spring Boot can bring the power of logic programming to your Java applications. 1. Setting Up Your Environment Add JPL Dependency: Include the Java Prolog Interface (JPL)\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_avkkoeavkkoeavkk.jpg?fit=1200%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_avkkoeavkkoeavkk.jpg?fit=1200%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_avkkoeavkkoeavkk.jpg?fit=1200%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_avkkoeavkkoeavkk.jpg?fit=1200%2C1200&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/Gemini_Generated_Image_avkkoeavkkoeavkk.jpg?fit=1200%2C1200&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3740,"url":"https:\/\/www.mymiller.name\/wordpress\/springboot\/threading-in-spring-a-comprehensive-guide\/","url_meta":{"origin":3641,"position":1},"title":"Threading in Spring: A Comprehensive Guide","author":"Jeffery Miller","date":"December 23, 2025","format":false,"excerpt":"Threading is a crucial aspect of building modern, high-performance applications. It allows you to execute multiple tasks concurrently, improving responsiveness and utilizing system resources effectively. Spring Framework provides robust support for managing and using threads, simplifying development and ensuring efficiency. This article explores thread usage in Spring, delves into different\u2026","rel":"","context":"In &quot;Springboot&quot;","block_context":{"text":"Springboot","link":"https:\/\/www.mymiller.name\/wordpress\/category\/springboot\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/ai-generated-8248619_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/ai-generated-8248619_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/ai-generated-8248619_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/ai-generated-8248619_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/ai-generated-8248619_1280-jpg.avif 3x"},"classes":[]},{"id":3724,"url":"https:\/\/www.mymiller.name\/wordpress\/spng_security\/spring-cors-configuration-a-comprehensive-guide\/","url_meta":{"origin":3641,"position":2},"title":"Spring CORS Configuration: A Comprehensive Guide","author":"Jeffery Miller","date":"December 18, 2025","format":false,"excerpt":"Cross-Origin Resource Sharing (CORS) is a security mechanism that browsers implement to restrict web pages from making requests to a different domain than the one that served the web page. This article provides a comprehensive guide to CORS configuration in Spring, covering both enabling and disabling CORS, along with the\u2026","rel":"","context":"In &quot;Spring Security&quot;","block_context":{"text":"Spring Security","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spng_security\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 3x"},"classes":[]},{"id":3786,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/integrating-easy-rules-with-a-spring-boot-microservice\/","url_meta":{"origin":3641,"position":3},"title":"Integrating Easy Rules with a Spring Boot Microservice","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"This post will walk you through integrating the lightweight and straightforward Easy Rules engine with your Spring Boot microservice. We'll cover the necessary dependencies, basic setup, and an example service to demonstrate its usage. 1. Project Setup and Dependencies Start by creating a Spring Boot project. Next, add the following\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 3x"},"classes":[]},{"id":3782,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/integrating-rulebook-with-a-spring-boot-microservice\/","url_meta":{"origin":3641,"position":4},"title":"Integrating RuleBook with a Spring Boot Microservice","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"This post guides you through integrating the RuleBook rule engine with your Spring Boot microservice. We\u2019ll cover adding the dependency, configuring RuleBook, and creating a service to utilize it. 1. Project Setup and Dependency Start by creating a Spring Boot project. Next, add the RuleBook dependency to your pom.xml (Maven)\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/board-3772063_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/board-3772063_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/board-3772063_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/board-3772063_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/board-3772063_1280-jpg.avif 3x"},"classes":[]},{"id":3574,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/deeplearning4j-and-spring-boot-a-powerful-duo-for-ai-powered-applications\/","url_meta":{"origin":3641,"position":5},"title":"Deeplearning4J and Spring Boot: A Powerful Duo for AI-Powered Applications","author":"Jeffery Miller","date":"April 20, 2026","format":false,"excerpt":"Deeplearning4J (DL4J) offers a comprehensive Java framework for deep learning, while Spring Boot streamlines the development of production-ready applications. By combining these two technologies, you unlock a flexible platform for building intelligent services that can handle various types of data. In this guide, we\u2019ll explore how to integrate DL4J into\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8453379_1280.jpg?fit=800%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8453379_1280.jpg?fit=800%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8453379_1280.jpg?fit=800%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/04\/ai-generated-8453379_1280.jpg?fit=800%2C1200&ssl=1&resize=700%2C400 2x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3641"}],"version-history":[{"count":2,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3641\/revisions"}],"predecessor-version":[{"id":3645,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3641\/revisions\/3645"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3642"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3641"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}