<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Keycloak Migration - Inero Software - Software Consulting</title>
	<atom:link href="https://inero-software.com/tag/keycloak-migration/feed/" rel="self" type="application/rss+xml" />
	<link>https://inero-software.com/tag/keycloak-migration/</link>
	<description>We unleash innovations using cutting-edge technologies, modern design and AI</description>
	<lastBuildDate>Fri, 14 Feb 2025 14:34:15 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://inero-software.com/wp-content/uploads/2018/11/inero-logo-favicon.png</url>
	<title>Keycloak Migration - Inero Software - Software Consulting</title>
	<link>https://inero-software.com/tag/keycloak-migration/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">153509928</site>	<item>
		<title>Keycloak Migration Made Easy: Tips and Best Practices</title>
		<link>https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/</link>
		
		<dc:creator><![CDATA[Marceli Formela]]></dc:creator>
		<pubDate>Tue, 28 Jan 2025 12:57:28 +0000</pubDate>
				<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[Keycloak Migration]]></category>
		<category><![CDATA[Multi-Factor Authentication]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=6799</guid>

					<description><![CDATA[<p>Here we’ll explore the most significant changes introduced in recent Keycloak releases and how they impact migration efforts. We’ll walk through practical examples to resolve common challenges, ensuring a smooth transition to newer versions. Whether it’s adapting to updated configurations or managing deprecated features, this post should provide additional tips&#8230;</p>
<p>Artykuł <a href="https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/">Keycloak Migration Made Easy: Tips and Best Practices</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="6799" class="elementor elementor-6799" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-bc9a077 e-flex e-con-boxed e-con e-parent" data-id="bc9a077" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-bef05bd e-con-full e-flex e-con e-child" data-id="bef05bd" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-27ad504 e-con-full e-flex e-con e-child" data-id="27ad504" data-element_type="container">
				<div class="elementor-element elementor-element-e3a7faf elementor-widget elementor-widget-html" data-id="e3a7faf" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
			 		</div>
				</div>
				<div class="elementor-element elementor-element-5d77ce3 elementor-widget elementor-widget-text-editor" data-id="5d77ce3" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h4><span style="font-weight: 400;">Here we’ll explore the most significant changes introduced in recent Keycloak releases and how they impact migration efforts. We’ll walk through practical examples to resolve common challenges, ensuring a smooth transition to newer versions. Whether it’s adapting to updated configurations or managing deprecated features, this post should provide additional tips to streamline your Keycloak migration process.</span></h4>						</div>
				</div>
				<div class="elementor-element elementor-element-9055b0b elementor-widget elementor-widget-heading" data-id="9055b0b" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Migrating to Quarkus distribution
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-c8c79fe elementor-widget elementor-widget-text-editor" data-id="c8c79fe" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">One of the most challenging migrations for many users has been the upgrade to Keycloak 17, where the underlying architecture shifted from WildFly to the Quarkus framework. This transition marked a significant departure from the traditional application server model, requiring users to adopt a more modern, lightweight approach tailored to Quarkus. The way Keycloak is configured has fundamentally changed &#8211; rather than deploying it on an external application server, it now operates as a standalone application, which simplifies deployment.</span></p><p><span style="font-weight: 400;">For example, custom providers, which were previously packaged dynamically as modules for WildFly, now need to be rebuilt and adapted (as runtime is immutable), involving changes to dependencies, classloading, and packaging methods. This design simplifies deployments in environments like Kubernetes but demands a shift in workflows for teams accustomed to the WildFly solutions. While the move to Quarkus offers performance gains and a more modern development experience, it still requires careful planning and testing to ensure a smooth migration.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-e39fb62 elementor-widget elementor-widget-heading" data-id="e39fb62" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Key changes introduced in new releases
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-9267062 elementor-widget elementor-widget-text-editor" data-id="9267062" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Migration introduces important changes that impact configuration, endpoints, and custom provider implementations:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-4465d06 elementor-widget elementor-widget-text-editor" data-id="4465d06" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li><b>HTTPS requirement for production mode </b><span style="font-weight: 400;">&#8211; starting Keycloak with the command [keycloak_quarkus_root]/26.1.0/bin/kc.bat start now requires an HTTPS certificate, as the start option is intended for production use. For local development, the start-dev option should be used instead.</span></li><li><b>removal of /auth from base path</b><span style="font-weight: 400;"> &#8211; the /auth segment has been removed from the default base path. Applications relying on Keycloak endpoints must update their configurations to reflect this change. </span></li><li><b>realm ID changes </b><span style="font-weight: 400;">&#8211; in previous versions, the realm ID was identical to the realm name. Starting from Keycloak 21, the realm ID is now a unique, system-generated value. Applications relying on realm IDs should account for this change during migration.</span></li><li><b>deprecation of userLocalStorage</b><span style="font-weight: 400;"> &#8211; custom providers using the userLocalStorage method of the KeycloakSession interface must switch to the users method, as userLocalStorage was deprecated starting from Keycloak 19.</span></li><li><b>transport jdbc-ping as new default</b><span style="font-weight: 400;"> &#8211; in the latest version of Keycloak (26.1.0), the default method for discovering other nodes within a cluster has shifted to using its database, rather than relying on just multicast. This change eliminates the need for additional network configurations, particularly in cloud environments.</span></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-f8db805 elementor-widget elementor-widget-heading" data-id="f8db805" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Issues with major migrations</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-c547a32 elementor-widget elementor-widget-text-editor" data-id="c547a32" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">When migrating Keycloak, it’s highly recommended to upgrade version by version, rather than jumping several releases at once. This incremental approach allows you to identify and resolve issues as they arise, minimizing the risk of unexpected complications. Upgrading across multiple versions—especially if spanning a dozen or more releases—can significantly complicate the process due to accumulated changes, deprecated features, and architectural shifts like the move to Quarkus. By addressing compatibility and configuration adjustments one step at a time, you ensure better control over the migration and reduce downtime or disruptions in production environments.</span></p><p><span style="font-weight: 400;">However, in many cases, a large one-time migration—such as moving from Keycloak 12 directly to Keycloak 26—is unavoidable and becomes a challenge that teams must address effectively. This process often involves significant changes to both the Keycloak server and dependent applications, particularly frontend clients that rely on its APIs. </span></p><p><span style="font-weight: 400;">In this guide, we’ll outline a practical step-by-step approach to such a major migration. </span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-45823ad elementor-widget elementor-widget-heading" data-id="45823ad" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Dockerfile configuration</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-ce32e89 elementor-widget elementor-widget-text-editor" data-id="ce32e89" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In our example project, all custom themes and SPI (Service Provider Interface) extensions were directly copied into the base Keycloak image without a dedicated build process. So it was done in a standard Wildfly way.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-4796eb9 elementor-widget elementor-widget-text-editor" data-id="4796eb9" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">FROM </span><span style="font-weight: 400;">quay.io</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak:</span><span style="font-weight: 400;">12.0.2<br /></span><span style="font-weight: 400;"><br /></span><span style="font-weight: 400;">COPY </span><span style="font-weight: 400;">themes</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">custom-theme </span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">opt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">jboss</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">themes/custom-theme</span><span style="font-weight: 400;"><br /></span><span style="font-weight: 400;">COPY </span><span style="font-weight: 400;">api-extensions</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">target</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">spi-resource-0</span><span style="font-weight: 400;">.0.1</span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">SNAPSHOT.jar<br /></span><span style="font-weight: 400;"><br /></span><span style="font-weight: 400;">ENTRYPOINT /</span><span style="font-weight: 400;">opt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">jboss</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">tools</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">docker-entrypoint.sh </span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">b </span><span style="font-weight: 400;">0.0.0.0</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-b1c75ea elementor-widget elementor-widget-text-editor" data-id="b1c75ea" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The new approach could use a multi-stage process with separate containers like:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-2f2a2de elementor-widget elementor-widget-text-editor" data-id="2f2a2de" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">FROM </span><span style="font-weight: 400;">eclipse-temurin:17-jdk as </span><i><span style="font-weight: 400;">spi_builder</span></i><br /><i><span style="font-weight: 400;">[…]</span></i><br /><span style="font-weight: 400;">FROM </span><span style="font-weight: 400;">quay.io</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak:$</span><i><span style="font-weight: 400;">BASE_IMAGE_TAG </span></i><span style="font-weight: 400;">as </span><i><span style="font-weight: 400;">keycloak_builder</span></i><br /><span style="font-weight: 400;">[…]</span><br /><span style="font-weight: 400;">FROM </span><span style="font-weight: 400;">quay.io</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak:$</span><i><span style="font-weight: 400;">BASE_IMAGE_TAG</span></i></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-a527627 elementor-widget elementor-widget-text-editor" data-id="a527627" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The SPI is built during the container build process using Maven. This approach ensures that the dependencies are fetched and the resulting JAR is optimized for deployment.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-0510f11 elementor-widget elementor-widget-text-editor" data-id="0510f11" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">### Runtime dependencies build container</span><br /><span style="font-weight: 400;">FROM </span><span style="font-weight: 400;">registry.access.redhat.com</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">ubi9 </span><span style="font-weight: 400;">AS </span><i><span style="font-weight: 400;">runtime_dependencies_builder</span></i><br /><span style="font-weight: 400;">RUN </span><span style="font-weight: 400;">mkdir </span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">p </span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">mnt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">rootfs</span><br /><br /><span style="font-weight: 400;">RUN </span><span style="font-weight: 400;">dnf </span><span style="font-weight: 400;">install </span><span style="font-weight: 400;">--</span><span style="font-weight: 400;">installroot </span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">mnt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">rootfs curl </span><span style="font-weight: 400;">--</span><span style="font-weight: 400;">releasever </span><span style="font-weight: 400;">9 </span><span style="font-weight: 400;">--</span><span style="font-weight: 400;">setopt install_weak_deps=false </span><span style="font-weight: 400;">--</span><span style="font-weight: 400;">nodocs </span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">y \</span><br /><span style="font-weight: 400;">&amp;&amp; </span><span style="font-weight: 400;">dnf </span><span style="font-weight: 400;">--</span><span style="font-weight: 400;">installroot </span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">mnt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">rootfs clean all</span><br /><br /><span style="font-weight: 400;">### SPI build container</span><br /><span style="font-weight: 400;">FROM </span><span style="font-weight: 400;">eclipse-temurin:17-jdk as </span><i><span style="font-weight: 400;">spi_builder</span></i><br /><span style="font-weight: 400;">ARG </span><i><span style="font-weight: 400;">BASE_IMAGE_TAG</span></i><br /><span style="font-weight: 400;">WORKDIR /</span><span style="font-weight: 400;">workspace</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">app</span><br /><br /><span style="font-weight: 400;">COPY </span><span style="font-weight: 400;">api-extensions</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">mvnw .</span><br /><span style="font-weight: 400;">COPY </span><span style="font-weight: 400;">api-extensions</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">.mvn .mvn</span><br /><span style="font-weight: 400;">COPY </span><span style="font-weight: 400;">api-extensions</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">pom.xml .</span><br /><br /><span style="font-weight: 400;"># dos2unix:</span><br /><span style="font-weight: 400;">RUN </span><span style="font-weight: 400;">sed </span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">i </span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">e </span><span style="font-weight: 400;">'s/\r//g' </span><span style="font-weight: 400;">mvnw</span><br /><span style="font-weight: 400;">RUN </span><span style="font-weight: 400;">./mvnw </span><span style="font-weight: 400;">dependency:go-offline</span><br /><span style="font-weight: 400;">COPY </span><span style="font-weight: 400;">api-extensions</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">src src</span><br /><span style="font-weight: 400;">RUN </span><span style="font-weight: 400;">./mvnw </span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">o package </span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">DskipTests</span><br /><span style="font-weight: 400;"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-9851247 elementor-widget elementor-widget-text-editor" data-id="9851247" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The new process copies multiple custom themes into the Quarkus-based Keycloak during the build stage, ensuring they are included in the final optimized runtime. So this approach improves startup performance and aligns with immutable container philosophy.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-0cd6583 elementor-widget elementor-widget-text-editor" data-id="0cd6583" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">### Build container</span><br /><span style="font-weight: 400;">FROM </span><span style="font-weight: 400;">quay.io</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak:$</span><i><span style="font-weight: 400;">BASE_IMAGE_TAG </span></i><span style="font-weight: 400;">as </span><i><span style="font-weight: 400;">keycloak_builder</span></i><br /><span style="font-weight: 400;">COPY --</span><span style="font-weight: 400;">from=</span><i><span style="font-weight: 400;">spi_builder </span></i><span style="font-weight: 400;">/</span><span style="font-weight: 400;">workspace</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">app</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">target</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">spi-resource-0</span><span style="font-weight: 400;">.0.1</span><span style="font-weight: 400;">-</span><span style="font-weight: 400;">SNAPSHOT-jar-with-dependencies.jar </span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">opt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">providers</span><span style="font-weight: 400;">/</span><br /><br /><span style="font-weight: 400;">#Copy custom themes</span><br /><span style="font-weight: 400;">COPY </span><span style="font-weight: 400;">themes</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">custom-theme </span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">opt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">themes</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">custom-theme</span><br /><br /><span style="font-weight: 400;">#Build an optimized server runtime</span><br /><span style="font-weight: 400;">RUN </span><span style="font-weight: 400;">/opt/keycloak/bin/kc.sh </span><span style="font-weight: 400;">build</span><br /><br /><span style="font-weight: 400;">### Runtime container</span><br /><span style="font-weight: 400;">FROM </span><a href="http://quay.io/keycloak/keycloak:$BASE_IMAGE_TAG"><span style="font-weight: 400;">quay.io/keycloak/keycloak:$</span><i><span style="font-weight: 400;">BASE_IMAGE_TAG</span></i></a><br /><span style="font-weight: 400;">COPY --</span><span style="font-weight: 400;">from=</span><i><span style="font-weight: 400;">keycloak_builder </span></i><span style="font-weight: 400;">/</span><span style="font-weight: 400;">opt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/ /</span><span style="font-weight: 400;">opt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">/</span><br /><span style="font-weight: 400;">WORKDIR /</span><span style="font-weight: 400;">opt</span><span style="font-weight: 400;">/</span><span style="font-weight: 400;">keycloak</span><br /><span style="font-weight: 400;">ENTRYPOINT </span><span style="font-weight: 400;">[</span><span style="font-weight: 400;">"/opt/keycloak/bin/kc.sh"</span><span style="font-weight: 400;">]</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-1dc220a elementor-widget elementor-widget-text-editor" data-id="1dc220a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Basically, by leveraging multi-stage builds and lightweight images, the new process aligns with best practices for containerized deployments. You can find more details about these steps here: </span><a href="https://www.keycloak.org/server/containers"><span style="font-weight: 400;">https://www.keycloak.org/server/containers</span></a><span style="font-weight: 400;">.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-15c9000 elementor-widget elementor-widget-heading" data-id="15c9000" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Default /auth context path changed
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-2ff8164 elementor-widget elementor-widget-text-editor" data-id="2ff8164" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">With the transition to the Quarkus-based Keycloak distribution, the default context path has been modified—/auth is no longer part of the URL by default. This change aligns with Quarkus’s goal of providing a more streamlined and minimalistic approach to web applications, reducing unnecessary path prefixes.</span></p><p><span style="font-weight: 400;">For users or applications that still require the /auth context path, it can be reintroduced using the http-relative-path build option. For instance, running Keycloak with the following command restores the /auth context:</span></p><p><b><i>bin/kc.[sh|bat] start-dev &#8211;http-relative-path /auth</i></b></p><p><span style="font-weight: 400;">Or using a docker-compose way:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-2ee41e2 elementor-widget elementor-widget-text-editor" data-id="2ee41e2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">KC_HTTP_RELATIVE_PATH</span><span style="font-weight: 400;">: /auth</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-27a0144 elementor-widget elementor-widget-text-editor" data-id="27a0144" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">This allows for compatibility with existing clients or configurations that rely on the /auth prefix. With the relative path specified, Keycloak will still automatically redirect requests from the root (e.g., localhost:8080/) to the /auth path (e.g., localhost:8080/auth). This ensures that applications or users accustomed to the previous URL structure continue to function as expected without requiring major changes.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-24a1365 elementor-widget elementor-widget-heading" data-id="24a1365" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Changes within provider management
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-557e06a elementor-widget elementor-widget-text-editor" data-id="557e06a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">With the shift to the Quarkus-based Keycloak distribution, there are significant changes in how custom providers (SPIs) are deployed and managed. In the WildFly-based distribution, custom providers were deployed by copying them into the </span><b><i>standalone/deployments</i></b><span style="font-weight: 400;"> directory, and dependencies were also placed in specific locations within the WildFly server structure. However, in the new Quarkus distribution, this deployment model has been streamlined. Custom providers should now be copied into the </span><b><i>/providers</i></b><span style="font-weight: 400;"> directory.</span></p><p><span style="font-weight: 400;">Additionally, Quarkus does not support the EAR packaging format or the jboss-deployment-structure.xml files, which were commonly used in the WildFly distribution to configure deployments and manage dependencies. As a result, the packaging process is simplified, but custom configurations previously made through these files must now be handled differently.</span></p><p><span style="font-weight: 400;">Furthermore, if custom providers utilized JavaEE APIs, such as session or stateless beans, these will no longer be supported in the Quarkus distribution.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-7391d60 elementor-widget elementor-widget-heading" data-id="7391d60" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Migrating custom themes
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-c0ccfee elementor-widget elementor-widget-text-editor" data-id="c0ccfee" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Old Keycloak relied on the FreeMarker template engine for rendering dynamic content in themes. This approach is still used in new releases (especially in v1 and v2 themes), but there have been updates to the template syntax and theme structure to align with the new Quarkus architecture. Custom templates may need to be revised to ensure compatibility with newer versions of FreeMarker, as the theme structure may have evolved.</span></p><p><span style="font-weight: 400;">Additionally, certain legacy template functions and macros that were present in, for example Keycloak 12, might have been deprecated or replaced with new, more efficient alternatives.</span></p><p><span style="font-weight: 400;">Custom themes that were previously customized are likely not optimized for dark mode. To avoid complications without having to rewrite them from scratch, the simplest solution is to add the appropriate option </span><b><i>darkMode=false</i></b><span style="font-weight: 400;"> in the </span><b><i>theme.properties</i></b><span style="font-weight: 400;"> file. Additionally, starting from version 26.1.0, the &#8220;Themes&#8221; tab now includes switches that allow for enabling dark mode on a per-realm basis.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-a573147 elementor-widget elementor-widget-heading" data-id="a573147" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Making new Keycloak server work with legacy frontend client
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-21c6dc8 elementor-widget elementor-widget-text-editor" data-id="21c6dc8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><b>checkLoginIframe related issues</b></p><p><span style="font-weight: 400;">In one of our projects, we had to upgrade Keycloak by 14 versions. However, for various reasons, we couldn&#8217;t migrate the frontend, which was running on a rather old version of Angular and the keycloak-angular library. Therefore, we will now go through the tweaks we had to apply in order to restore the login process functionality.</span></p><p><span style="font-weight: 400;">Keycloak-angular is a wrapper library for keycloak-js that makes using it easier in Angular applications. It extends the original features with additional functionality and adds new methods to make it easier to use within an Angular app. It also provides a basic implementation of AuthGuard, allowing you to customize your logic by using the authentication logic. It’s also possible to use the HttpClient Interceptor, which adds an authorization header to selected HTTP requests.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-43ca3b8 elementor-widget elementor-widget-text-editor" data-id="43ca3b8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">"keycloak-angular"</span><span style="font-weight: 400;">: </span><span style="font-weight: 400;">"^8.1.0"</span><span style="font-weight: 400;">,</span><br /><span style="font-weight: 400;">"keycloak-js"</span><span style="font-weight: 400;">: </span><span style="font-weight: 400;">"^12.0.4"</span><span style="font-weight: 400;">,</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-2699e08 elementor-widget elementor-widget-text-editor" data-id="2699e08" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">After integrating the new version of Keycloak (26.1.0) with the old frontend client, we encountered an issue after logging in, which manifested as follows:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-81f2826 elementor-widget elementor-widget-image" data-id="81f2826" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img fetchpriority="high" decoding="async" data-attachment-id="6801" data-permalink="https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/2025-01-28/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28.png" data-orig-size="538,317" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-01-28" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-300x177.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28.png" tabindex="0" role="button" width="480" height="317" src="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-480x317.png" class="attachment-septera-lpbox-2 size-septera-lpbox-2 wp-image-6801" alt="" data-attachment-id="6801" data-permalink="https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/2025-01-28/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28.png" data-orig-size="538,317" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-01-28" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-300x177.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-91587be elementor-widget elementor-widget-text-editor" data-id="91587be" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">This option specifies whether Keycloak should check the login status using an iframe. It should be used with caution, as improper configuration may lead to issues such as continuous page reloads. Newer versions of Keycloak may have improved or changed session management, particularly around cross-site cookies, authentication flows, or iframe handling (setupCheckLoginIframe, check3pCookiesSupported). These changes could affect how the frontend handles login states, especially if it is using deprecated methods for checking login states or processing callbacks.</span></p><p><span style="font-weight: 400;">Given the significant version gap between the frontend and the server, one useful approach might be to </span><b>disable the setupCheckLoginIframe option</b><span style="font-weight: 400;">, which could also help in situations where infinite redirect loops occur after the upgrade.</span></p><p><span style="font-weight: 400;">Here’s an example of how to disable it in your initialization:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-f530026 elementor-widget elementor-widget-text-editor" data-id="f530026" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">function </span><span style="font-weight: 400;">initializeKeycloak</span><span style="font-weight: 400;">(keycloak: KeycloakService, permissionsService: PermissionsService) </span><br /><span style="font-weight: 400;">{</span><br /><span style="font-weight: 400;">  </span><span style="font-weight: 400;">return </span><span style="font-weight: 400;">() =&gt;</span><br /><span style="font-weight: 400;">    keycloak.</span><span style="font-weight: 400;">init</span><span style="font-weight: 400;">({</span><br /><br /><span style="font-weight: 400;">  </span> <span style="font-weight: 400;">config</span><span style="font-weight: 400;">: {</span><br /><span style="font-weight: 400;">    </span> <span style="font-weight: 400;">url</span><span style="font-weight: 400;">: </span><i><span style="font-weight: 400;">environment</span></i><span style="font-weight: 400;">.</span><span style="font-weight: 400;">keycloakUrl</span><span style="font-weight: 400;">,</span><br /><span style="font-weight: 400;">    </span> <span style="font-weight: 400;">realm</span><span style="font-weight: 400;">: </span><span style="font-weight: 400;">'test-realm'</span><span style="font-weight: 400;">,</span><br /><span style="font-weight: 400;">    </span> <span style="font-weight: 400;">clientId</span><span style="font-weight: 400;">: </span><span style="font-weight: 400;">'test-realm-web'</span><span style="font-weight: 400;">,</span><br /><span style="font-weight: 400;">  </span> <span style="font-weight: 400;">},</span><br /><span style="font-weight: 400;">  </span> <span style="font-weight: 400;">initOptions</span><span style="font-weight: 400;">: {</span><br /><span style="font-weight: 400;">        </span><span style="font-weight: 400;">checkLoginIframe</span><span style="font-weight: 400;">: </span><span style="font-weight: 400;">false</span><br /><span style="font-weight: 400;">  </span> <span style="font-weight: 400;">}</span><br /><span style="font-weight: 400;">}).</span><span style="font-weight: 400;">then</span><span style="font-weight: 400;">(() =&gt; permissionsService.</span><span style="font-weight: 400;">init</span><span style="font-weight: 400;">());</span><br /><span style="font-weight: 400;">}</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-eaf0ada elementor-widget elementor-widget-heading" data-id="eaf0ada" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Missing nonce claim
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-9e105aa elementor-widget elementor-widget-text-editor" data-id="9e105aa" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In newer versions of Keycloak, in accordance with the OpenID Connect Core 1.0 specification, the nonce claim is now only added to the ID token if the parameter was included in the authorization request. According to the specification, the nonce claim is mandatory in the ID token but should not be included in tokens after a refresh request. Previously, nonce was added to all tokens (Access, Refresh, and ID) in all responses, including refresh responses.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-fc3ca51 elementor-widget elementor-widget-image" data-id="fc3ca51" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img decoding="async" data-attachment-id="6802" data-permalink="https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/2025-01-28-2/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-2.png" data-orig-size="716,448" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-01-28 -2" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-2-300x188.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-2.png" tabindex="0" role="button" width="512" height="300" src="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-2-512x300.png" class="attachment-septera-featured-third size-septera-featured-third wp-image-6802" alt="" data-attachment-id="6802" data-permalink="https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/2025-01-28-2/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-2.png" data-orig-size="716,448" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-01-28 -2" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-2-300x188.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/01/2025-01-28-2.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-8016f49 elementor-widget elementor-widget-text-editor" data-id="8016f49" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">As a result, using an older version of the keycloak-js adapter may cause login issues, such as &#8220;Invalid nonce, clearing token&#8221; errors or an infinite redirection loop after login attempts. To resolve this, users can add the predefined &#8220;Nonce backwards compatible&#8221; mapper via the &#8220;By Configuration&#8221; button in the dedicated client scope. More information can be found in the official Keycloak documentation </span><span style="font-weight: 400;">(</span><a href="https://www.keycloak.org/docs/latest/upgrading/index.html#nonce-claim-is-only-added-to-the-id-token"><span style="font-weight: 400;">https://www.keycloak.org/docs/latest/upgrading/index.html#nonce-claim-is-only-added-to-the-id-token</span></a><span style="font-weight: 400;">)</span><span style="font-weight: 400;">.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-5c61c2e elementor-widget elementor-widget-heading" data-id="5c61c2e" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Post-logout redirect URI issues
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-26180df elementor-widget elementor-widget-text-editor" data-id="26180df" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">According to the release notes for version 18, Keycloak no longer supports the redirect_uri parameter for logging out. Instead, you need to use post_logout_redirect_uri along with either the client_id or id_token_hint parameter. In practice, this means when calling the logout function, you must replace redirect_uri with post_logout_redirect_uri. In our case (with legacy keycloak-js), the logout process can be implemented like this:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-a8f685a elementor-widget elementor-widget-text-editor" data-id="a8f685a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><i><span style="font-weight: 400;">window</span></i><span style="font-weight: 400;">.</span><span style="font-weight: 400;">location</span><span style="font-weight: 400;">.</span><span style="font-weight: 400;">replace</span><span style="font-weight: 400;">(</span><span style="font-weight: 400;">this</span><span style="font-weight: 400;">.</span><span style="font-weight: 400;">keycloak</span><span style="font-weight: 400;">[</span><span style="font-weight: 400;">'_instance'</span><span style="font-weight: 400;">][</span><span style="font-weight: 400;">'endpoints'</span><span style="font-weight: 400;">].</span><span style="font-weight: 400;">logout</span><span style="font-weight: 400;">() +</span><span style="font-weight: 400;"><br /></span><span style="font-weight: 400;">   </span><span style="font-weight: 400;">'?post_logout_redirect_uri=' </span><span style="font-weight: 400;">+ </span><span style="font-weight: 400;">encodeURIComponent</span><span style="font-weight: 400;">(</span><i><span style="font-weight: 400;">window</span></i><span style="font-weight: 400;">.</span><span style="font-weight: 400;">location</span><span style="font-weight: 400;">.</span><span style="font-weight: 400;">origin</span><span style="font-weight: 400;">) +</span><span style="font-weight: 400;"><br /></span><span style="font-weight: 400;">   </span><span style="font-weight: 400;">'&amp;client_id=test-realm-web'</span><span style="font-weight: 400;">);</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-d4ca7eb elementor-widget elementor-widget-text-editor" data-id="d4ca7eb" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">This change should resolve the most common issues with redirects after logging out of the application.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-20e2094 elementor-widget elementor-widget-heading" data-id="20e2094" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Summary
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-5633025 elementor-widget elementor-widget-text-editor" data-id="5633025" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Over the past few years, Keycloak has undergone significant changes, particularly with the breaking changes introduced during the migration from WildFly to Quarkus. These changes were necessary for performance improvements, more efficient resource usage, and better scalability.</span></p><p><span style="font-weight: 400;">While the migration process can appear challenging, it is generally achievable, even when working with older clients. However, the ease of migration largely depends on the specific use case, especially the level of customization involved. For instance, if themes were highly customized in the previous version of Keycloak, adapting them to newer distributions may require more time and effort, as the structure and templating engines have evolved.</span></p><p><span style="font-weight: 400;">Similarly, integrations with legacy systems might need careful planning to ensure compatibility with newer versions of Keycloak. On the other hand, for standard setups with minimal customization, the transition is often smoother and quicker. The process of migration can also be supported by detailed documentation and a strong community, which has grown significantly in recent years.</span></p><p><span style="font-weight: 400;">Overall, while each migration project has its own challenges, with proper planning and testing, transitioning to a newer version of Keycloak is generally not so complicated, and the long-term benefits of the upgrade, such as improved performance and security features, make it worth the effort.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-c667383 elementor-cta--skin-cover elementor-animated-content elementor-bg-transform elementor-bg-transform-zoom-in elementor-widget elementor-widget-call-to-action" data-id="c667383" data-element_type="widget" data-widget_type="call-to-action.default">
				<div class="elementor-widget-container">
					<div class="elementor-cta">
					<div class="elementor-cta__bg-wrapper">
				<div class="elementor-cta__bg elementor-bg" style="background-image: url(https://inero-software.com/wp-content/uploads/2024/12/1-1030x1030.png);" role="img" aria-label="1"></div>
				<div class="elementor-cta__bg-overlay"></div>
			</div>
							<div class="elementor-cta__content">
				
									<h2 class="elementor-cta__title elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						Are you planning to implement Keycloak in your organization? 					</h2>
				
									<div class="elementor-cta__description elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						If you're looking for a partner to provide comprehensive support in this process, be sure to contact us.					</div>
				
									<div class="elementor-cta__button-wrapper elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
					<a class="elementor-cta__button elementor-button elementor-size-" href="https://calendar.app.google/CiGcgpfTyvVHDizZ8">
						Schedule a conversation					</a>
					</div>
							</div>
						</div>
				</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-bece524 e-con-full e-flex e-con e-child" data-id="bece524" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-54593f6 e-flex e-con-boxed e-con e-parent" data-id="54593f6" data-element_type="container">
					<div class="e-con-inner">
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/">Keycloak Migration Made Easy: Tips and Best Practices</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6799</post-id>	</item>
	</channel>
</rss>
