<?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/"
	>

<channel>
	<title>keep_growing</title>
	<atom:link href="https://keepgrowing.in/feed/" rel="self" type="application/rss+xml" />
	<link>https://keepgrowing.in/</link>
	<description>Software development with care</description>
	<lastBuildDate>Fri, 08 Apr 2022 08:01:29 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://keepgrowing.in/wp-content/uploads/2018/02/cropped-logo_upper-32x32.png</url>
	<title>keep_growing</title>
	<link>https://keepgrowing.in/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">173794879</site>	<item>
		<title>Simplify the management of user roles in Spring Boot</title>
		<link>https://keepgrowing.in/java/springboot/simplify-the-management-of-user-roles-in-spring-boot/</link>
					<comments>https://keepgrowing.in/java/springboot/simplify-the-management-of-user-roles-in-spring-boot/#respond</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Fri, 25 Mar 2022 10:49:23 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[user management]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=9770</guid>

					<description><![CDATA[<p>Spring Security allows us to use role-based control to restrict access to API resources. However, inserting role names as simple strings can quickly become cumbersome and increase development cost. Fortunately, we can enclose role details in an Enum and use custom annotations to simplify management of user roles in a Spring Boot application. While it still doesn&#8217;t provide type-safe roles, most IDEs will be able to support changes in the code and simplify maintenance. Prerequsites As an example for this article, I&#8217;m going to configure role-based access control. If you want to recreate the work described below, you&#8217;re going to need a Spring Boot project with: a REST controller with at least one endpoint, spring-boot-starter-security and spring-security-test dependencies. You can find an example project in the spring-boot-user-roles-management repository. Summarizing the work described below: first I will create an example role and add it to my default user via the application properties. Then I will restrict access to POST endpoints to only users with this role. Finally, I am going to include new access rules in my MVC tests. Create Enum for user roles I&#8217;m going to start with creating a class for user roles. In straightforward cases, a simple Enum will suffice. However, if we need to encapsulate a role name that does not follow the Enum naming convention, we need to add an additional field for the value. Below you&#8217;ll find solutions for both situations. Roles in a simple Enum For a simple use case, I&#8217;m going to create the following UserRole Enum with a single role: In my sample project, I defined a default user with the spring.security.user.* properties. Now, I have to add the role in my application.properties file: Thanks to this, the application starts with a default user who already has the authority and I will be able to quickly test my configuration later: Role name as Enum value In case we don&#8217;t have control over the role names (e.g. they are created in an external authorization service like Keycloak and may look like chief-operation-officer), we can still provide a convenient mapping. We just need to encapsulate the external name in an Enum value and override the toString() method: As before, I need to add the role to my default user defined with the spring.security.user.* properties: Security configuration We can define role-based security rules in the HttpSecurity configuration or for each method / class. Below you&#8217;ll find example implementation for both cases. Specify access rules in the HttpSecurity config In the following HttpSecurity configuration, I&#8217;m going to allow only users with the required role to access POST endpoints: As a result, POST endpoints will be inaccessible to anyone except a COO. As a side note, I&#8217;m using the authorizeHttpRequests() method because it seems that autorizeRequests() will be deprecated. Furthermore, you can use mvcMatchers() instead of antMatchers() if you need a different approach to pattern matching, like in the snippet below: Verify user role at the method level When we need more precise access control, we can apply method level security. First, I&#8217;m going to enable method security using the following class: Annotate your class with @EnableGlobalMethodSecurity if you use Spring Security version &#60; 5.6. Next, I&#8217;m going to add the @PreAuthorize annotation onto the example POST endpoint: Unfortunately, we have to use the fully-qualified path in the SpEL expression. Obviously, I don&#8217;t want to clutter controllers with such low-level details. Therefore, I&#8217;m going to create a custom annotation. Create a custom annotation to hide irrelevant details Luckily, creating a meta annotation is simple: Let&#8217;s take a look at the annotations I&#8217;m using here: @Target – puts constrains on the usage of the annotation. The TYPE Element Type allows using it on a class (e.g. controller classes), interface, Enum or record declaration. I&#8217;m also providing the METHOD as a possible target to allow using this annotation on a single endpoint. @Retention –&#160;specifies how long an annotation is to be retained. The RUNTIME Retention Policy enables the annotation to be retained by the VM at run time. @PreAuthorize – the original annotation that I want to remove from the controller code. As a result, all irrelevant details remain hidden from my controllers: Summary By keeping user roles in Enum and using them in annotations as described above, we can take advantage of our IDE when maintaining the authorities. Tests Unfortunately, I haven&#8217;t found a convenient method of using Enum when mocking a user role in tests. Therefore, as we can see in the snippet below, we still have to provide the required role as a simple String: To simplify maintenance of the tests, we can create our custom annotation to mock users with the CHIEF_OPERATING_OFFICER role: For more advanced mapping, when we keep the actual user role in the Enum value: As a result, we don&#8217;t have to provide user role as a string in every test class or test method: Read more on simplifying roles management in Spring How to create typesafe user roles for Spring Security? Spring Security @PreAuthorization pass enums in directly Keycloak with Spring Boot #4 – Simple guide for roles and authorities Photo by&#160;Kindel Media&#160;from&#160;Pexels</p>
<p>The post <a href="https://keepgrowing.in/java/springboot/simplify-the-management-of-user-roles-in-spring-boot/">Simplify the management of user roles in Spring Boot</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Spring Security allows us to use role-based control to restrict access to API resources. However, inserting role names as simple strings can quickly become cumbersome and increase development cost. Fortunately, we can enclose role details in an Enum and use custom annotations to simplify management of user roles in a Spring Boot application. While it still doesn&#8217;t provide type-safe roles, most IDEs will be able to support changes in the code and simplify maintenance.</p>



<span id="more-9770"></span>



<h2 class="wp-block-heading">Prerequsites</h2>



<p class="wp-block-paragraph">As an example for this article, I&#8217;m going to configure role-based access control. If you want to recreate the work described below, you&#8217;re going to need a Spring Boot project with:</p>



<ul class="wp-block-list"><li>a REST controller with at least one endpoint,</li><li><a href="https://docs.spring.io/spring-security/reference/getting-spring-security.html" target="_blank" rel="noreferrer noopener">spring-boot-starter-security</a> and <a href="https://mvnrepository.com/artifact/org.springframework.security/spring-security-test" target="_blank" rel="noreferrer noopener">spring-security-test</a> dependencies.</li></ul>



<p class="wp-block-paragraph">You can find an example project in the <a href="https://github.com/little-pinecone/spring-boot-user-roles-management" target="_blank" rel="noreferrer noopener">spring-boot-user-roles-management</a> repository.</p>



<p class="wp-block-paragraph">Summarizing the work described below: first I will create an example role and add it to my default user via the application properties. Then I will restrict access to POST endpoints to only users with this role. Finally, I am going to include new access rules in my MVC tests.</p>



<h2 class="wp-block-heading">Create Enum for user roles</h2>



<p class="wp-block-paragraph">I&#8217;m going to start with creating a class for user roles. In straightforward cases, a simple Enum will suffice. However, if we need to encapsulate a role name that does not follow the Enum naming convention, we need to add an additional field for the value. Below you&#8217;ll find solutions for both situations.</p>



<h3 class="wp-block-heading">Roles in a simple Enum</h3>



<p class="wp-block-paragraph">For a simple use case, I&#8217;m going to create the following <code>UserRole</code> Enum with a single role:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.security.domain.model;

public enum UserRole {

    CHIEF_OPERATING_OFFICER
}</pre></div>



<p class="wp-block-paragraph">In my sample project, I defined a default user with the <code>spring.security.user.*</code> properties. Now, I have to add the role in my <code>application.properties</code> file:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag"># application.properties
…
spring.security.user.roles=CHIEF_OPERATING_OFFICER</pre></div>



<p class="wp-block-paragraph">Thanks to this, the application starts with a default user who already has the authority and I will be able to quickly test my configuration later:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="1190" height="167" src="https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs.webp" alt="type safe user role in spring Security Granted Authorities" class="wp-image-9945" srcset="https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs.webp 1190w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-300x42.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-1024x144.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-768x108.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-700x98.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-520x73.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-360x51.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-250x35.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/03/authorities-in-logs-100x14.webp 100w" sizes="(max-width: 1190px) 100vw, 1190px" /></figure></div>



<h3 class="wp-block-heading">Role name as Enum value</h3>



<p class="wp-block-paragraph">In case we don&#8217;t have control over the role names (e.g. they are created in an external authorization service like Keycloak and may look like <code>chief-operation-officer</code>), we can still provide a convenient mapping. We just need to encapsulate the external name in an Enum value and override the <code>toString()</code> method:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.security.domain.model;

public enum UserRole {

    CHIEF_OPERATING_OFFICER("chief-operating-officer");

    final String value;

    UserRole(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return value;
    }
}</pre></div>



<p class="wp-block-paragraph">As before, I need to add the role to my default user defined with the <code>spring.security.user.*</code> properties:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag"># application.properties
…
spring.security.user.roles=chief-operating-officer</pre></div>



<h2 class="wp-block-heading">Security configuration</h2>



<p class="wp-block-paragraph">We can define role-based security rules in the HttpSecurity configuration or for each method / class. Below you&#8217;ll find example implementation for both cases.</p>



<h3 class="wp-block-heading">Specify access rules in the HttpSecurity config</h3>



<p class="wp-block-paragraph">In the following <a href="https://docs.spring.io/spring-security/reference/servlet/authorization/authorize-http-requests.html" target="_blank" rel="noreferrer noopener">HttpSecurity configuration</a>, I&#8217;m going to allow only users with the required role to access POST endpoints:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.security.config;

import in.keepgrowing.springbootuserrolesmanagement.security.domain.model.UserRole;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
…
protected void configure(HttpSecurity http) throws Exception {
    …
    .authorizeHttpRequests()
    .antMatchers(HttpMethod.POST).hasRole(UserRole.CHIEF_OPERATING_OFFICER.toString())
    .anyRequest().authenticated()
…</pre></div>



<p class="wp-block-paragraph">As a result, POST endpoints will be inaccessible to anyone except a <code>COO</code>.</p>



<p class="wp-block-paragraph">As a side note, I&#8217;m using the <code>authorizeHttpRequests()</code> method because it seems that <a href="https://github.com/spring-projects/spring-security/issues/10573" target="_blank" rel="noreferrer noopener">autorizeRequests() will be deprecated</a>. Furthermore, you can use <code>mvcMatchers()</code> instead of <code>antMatchers()</code> if you need a different approach to <a href="https://stackoverflow.com/questions/50536292/difference-between-antmatcher-and-mvcmatcher" target="_blank" rel="noreferrer noopener">pattern matching</a>, like in the snippet below:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
.mvcMatchers(HttpMethod.POST, "/example").hasRole(UserRole.CHIEF_OPERATING_OFFICER.toString())</pre></div>



<h3 class="wp-block-heading">Verify user role at the method level</h3>



<p class="wp-block-paragraph">When we need more precise access control, we can apply <a href="https://docs.spring.io/spring-security/reference/servlet/authorization/expression-based.html#_method_security_expressions" target="_blank" rel="noreferrer noopener">method level security</a>. First, I&#8217;m going to <a href="https://docs.spring.io/spring-security/reference/servlet/authorization/method-security.html#_enablemethodsecurity" target="_blank" rel="noreferrer noopener">enable method security</a> using the following class:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.security.config;

import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;

@EnableMethodSecurity
public class CustomMethodSecurityConfig {
}</pre></div>



<p class="wp-block-paragraph">Annotate your class with <code>@EnableGlobalMethodSecurity</code> if you use Spring Security version &lt; 5.6.</p>



<p class="wp-block-paragraph">Next, I&#8217;m going to add the <code>@PreAuthorize</code> annotation onto the example POST endpoint:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.example.adapters.driving.api.controllers;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleController {

    @PostMapping
    @PreAuthorize("hasRole(T(in.keepgrowing.springbootuserrolesmanagement.security.domain.model.UserRole).CHIEF_OPERATING_OFFICER.toString())")
    public ResponseEntity&lt;Void&gt; post() {
        return ResponseEntity.ok().build();
    }
…</pre></div>



<p class="wp-block-paragraph">Unfortunately, we have to use the fully-qualified path in the <a href="https://docs.spring.io/spring-framework/docs/5.3.16/reference/html/core.html#expressions" target="_blank" rel="noreferrer noopener">SpEL</a> expression. Obviously, I don&#8217;t want to clutter controllers with such low-level details. Therefore, I&#8217;m going to create a custom annotation.</p>



<h4 class="wp-block-heading">Create a custom annotation to hide irrelevant details</h4>



<p class="wp-block-paragraph">Luckily, creating a <a href="https://docs.spring.io/spring-security/reference/servlet/authorization/expression-based.html#_method_security_meta_annotations" target="_blank" rel="noreferrer noopener">meta annotation</a> is simple:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.security.adapters.driving.spring.annotations;

import org.springframework.security.access.prepost.PreAuthorize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize(value = "hasRole(T(in.keepgrowing.springbootuserrolesmanagement.security.domain.model.UserRole).CHIEF_OPERATING_OFFICER.toString())")
public @interface MustBeChiefOperatingOfficer {
}</pre></div>



<p class="wp-block-paragraph">Let&#8217;s take a look at the annotations I&#8217;m using here:</p>



<ol class="wp-block-list"><li><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/Target.html" target="_blank" rel="noreferrer noopener">@Target</a> – puts constrains on the usage of the annotation. The <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/ElementType.html#TYPE" target="_blank" rel="noreferrer noopener">TYPE</a> <code>Element Type</code> allows using it on a class (e.g. controller classes), interface, Enum or record declaration. I&#8217;m also providing the <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/ElementType.html#METHOD" target="_blank" rel="noreferrer noopener">METHOD</a> as a possible target to allow using this annotation on a single endpoint.</li><li><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/Retention.html" target="_blank" rel="noreferrer noopener">@Retention</a> –&nbsp;specifies how long an annotation is to be retained. The <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/RetentionPolicy.html#RUNTIME" target="_blank" rel="noreferrer noopener">RUNTIME</a> Retention Policy enables the annotation to be retained by the VM at run time.</li><li><a href="https://docs.spring.io/spring-security/reference/servlet/authorization/expression-based.html#el-pre-post-annotations" target="_blank" rel="noreferrer noopener">@PreAuthorize</a><span style="color: initial;"> – </span>the original annotation that I want to remove from the controller code.</li></ol>



<p class="wp-block-paragraph">As a result, all irrelevant details remain hidden from my controllers:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.example.adapters.driving.api.controllers;

import in.keepgrowing.springbootuserrolesmanagement.security.adapters.driving.spring.annotations.MustBeChiefOperatingOfficer;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleController {

    @PostMapping
    @MustBeChiefOperatingOfficer
    public ResponseEntity&lt;Void&gt; post() {
        return ResponseEntity.ok().build();
    }
…</pre></div>



<h3 class="wp-block-heading">Summary</h3>



<p class="wp-block-paragraph">By keeping user roles in Enum and using them in annotations as described above, we can take advantage of our IDE when maintaining the authorities.</p>



<h2 class="wp-block-heading">Tests</h2>



<p class="wp-block-paragraph">Unfortunately, I haven&#8217;t found a convenient method of using Enum when mocking a user role in tests. Therefore, as we can see in the snippet below, we still have to provide the required role as a simple String:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.example.adapters.driving.api.controllers;

import in.keepgrowing.springbootuserrolesmanagement.testing.annotations.WithMockChiefOperationOfficer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest
class ExampleControllerTest {

    private static final String PATH = "/" + ExampleControllerPaths.EXAMPLE_PATH;

    @Autowired
    private MockMvc mvc;

    @Test
    @WithMockUser(roles = "CHIEF_OPERATING_OFFICER")
    void shouldCallPostEndpoint() throws Exception {
        mvc.perform(post(PATH)
                        .with(csrf()))
                .andExpect(status().isOk());
    }
…</pre></div>



<p class="wp-block-paragraph">To simplify maintenance of the tests, we can create our custom annotation to mock users with the CHIEF_OPERATING_OFFICER role:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.testing.annotations;

import org.springframework.security.test.context.support.WithMockUser;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@WithMockUser(roles = "CHIEF_OPERATING_OFFICER")
public @interface WithMockChiefOperationOfficer {
}</pre></div>



<p class="wp-block-paragraph">For more advanced mapping, when we keep the actual user role in the Enum value:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.testing.annotations;
…
@WithMockUser(roles = "chief-operating-officer")
public @interface WithMockChiefOperationOfficer {
}</pre></div>



<p class="wp-block-paragraph">As a result, we don&#8217;t have to provide user role as a string in every test class or test method:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootuserrolesmanagement.example.adapters.driving.api.controllers;

import in.keepgrowing.springbootuserrolesmanagement.testing.annotations.WithMockChiefOperationOfficer;
…
    @Test
    @WithMockChiefOperationOfficer
    void shouldDenyAccessToPostEndpoint() throws Exception {
        mvc.perform(post(PATH)
                        .with(csrf()))
                .andExpect(status().isForbidden());
    }
…</pre></div>



<h2 class="wp-block-heading">Read more on simplifying roles management in Spring</h2>



<ul class="wp-block-list"><li><a href="https://stackoverflow.com/questions/23630097/how-to-create-typesafe-user-roles-for-spring-security" target="_blank" rel="noreferrer noopener">How to create typesafe user roles for Spring Security?</a></li><li><a href="https://stackoverflow.com/questions/19303584/spring-security-preauthorization-pass-enums-in-directly" target="_blank" rel="noreferrer noopener">Spring Security @PreAuthorization pass enums in directly</a></li><li><a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-4-simple-guide-for-roles-and-authorities/" target="_blank" rel="noreferrer noopener">Keycloak with Spring Boot #4 – Simple guide for roles and authorities</a></li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@kindelmedia?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Kindel Media</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/a-woman-wearing-safety-glasses-while-smiling-8325969/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/java/springboot/simplify-the-management-of-user-roles-in-spring-boot/">Simplify the management of user roles in Spring Boot</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/java/springboot/simplify-the-management-of-user-roles-in-spring-boot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">9770</post-id>	</item>
		<item>
		<title>Create a custom annotation to configure Spring Boot tests</title>
		<link>https://keepgrowing.in/java/springboot/create-a-custom-annotation-to-configure-spring-boot-tests/</link>
					<comments>https://keepgrowing.in/java/springboot/create-a-custom-annotation-to-configure-spring-boot-tests/#respond</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Sun, 06 Mar 2022 13:23:07 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[testing]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=9707</guid>

					<description><![CDATA[<p>A custom annotation in Spring Boot tests is an easy and flexible way to provide the required configuration. We can use it to efficiently group all the annotations and configuration classes that we would otherwise apply to each test class separately. Prerequisites As an example for this article, I&#8217;m going to create a custom annotation to configure controller tests. If you want to recreate the work described below, you will need a Spring Boot project with a REST controller and some MVC tests. Why use a custom annotation in Spring Boot tests One reason is to simply group all the annotations we need to apply across multiple test classes into convenient metadata. Moreover, it&#8217;s also useful when you use @Import to register additional components required for configuring the &#8220;slice&#8221; of the system to test, as it reduces a lot of copy-and-paste code. Another possible solution would be to create a base class and making each test extend it. However, inheritance comes with a lot of issues that I don&#8217;t want to deal with just to provide a common configuration for some tests. A custom annotation that encloses all the common configurations for tests is both an elegant and simple solution. In the following example, instead of annotating my tests with @WebMvcTest and @Import, I&#8217;m going to create @RestControllerIntegrationTest which will take care of all the configuration details. Thanks to this, I will avoid duplicating the code or complicating it with unnecessary inheritance. Create a custom annotation for MVC tests First, I&#8217;m going to replace the @WebMvcTest annotation with a custom one. I&#8217;m going to create the following RestControllerIntegrationTest annotation: Let&#8217;s take a look at the annotations I&#8217;m using here: @Retention –&#160;specifies how long an annotation is to be retained. The RUNTIME Retention Policy enables the annotation to be retained by the VM at run time. @Target – puts constrains on the usage of the annotation. The TYPE Element Type will allow using it on my test classes. @WebMvcTest – since I am creating my own annotation for MVC tests, i need to include this Spring Boot annotation to still benefit from all the default features. Thus, I can now replace @WebMvcTest with @RestControllerIntegrationTest and still have the same functionality: Now, I can add any additional configuration my test &#8220;slice&#8221; requires to the custom annotation. Provide additional configuration In my example project, I&#8217;m using the @PreAuthorize annotation to restrict user access to the API endpoints. Therefore, I need to enable method-level security. Without it, the following test fails because it is missing the configuration required to apply the appropriate access control: For that reason, I&#8217;m going to create a configuration class and annotate it with @EnableMethodSecurity: Next, I&#8217;ll load it into ApplicationContext using @ContextConfiguration in my custom annotation: Verify results As a result, all tests in classes annotated with @RestControllerIntegrationTest will be able to use method-level security. The following screenshot shows that my tests are passing now: Read more about setting up tests in Spring Boot Spring Boot test slices with custom annotations Document how to use this if Keycloak is on the classpath My other posts regarding testing Photo by&#160;Georgia Maciel&#160;from&#160;Pexels</p>
<p>The post <a href="https://keepgrowing.in/java/springboot/create-a-custom-annotation-to-configure-spring-boot-tests/">Create a custom annotation to configure Spring Boot tests</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">A custom annotation in Spring Boot tests is an easy and flexible way to provide the required configuration. We can use it to efficiently group all the annotations and configuration classes that we would otherwise apply to each test class separately.</p>



<span id="more-9707"></span>



<h2 class="wp-block-heading">Prerequisites</h2>



<p class="wp-block-paragraph">As an example for this article, I&#8217;m going to create a custom annotation to configure controller tests. If you want to recreate the work described below, you will need a Spring Boot project with a REST controller and some <a href="https://docs.spring.io/spring-boot/docs/2.6.4/reference/htmlsingle/#features.testing.spring-boot-applications.spring-mvc-tests" target="_blank" rel="noreferrer noopener">MVC tests</a>.</p>



<h2 class="wp-block-heading">Why use a custom annotation in Spring Boot tests</h2>



<p class="wp-block-paragraph">One reason is to simply group all the annotations we need to apply across multiple test classes into convenient metadata. Moreover, it&#8217;s also useful when you use <code>@Import</code> to register additional components required for <a href="https://docs.spring.io/spring-boot/docs/2.6.4/reference/htmlsingle/#features.testing.spring-boot-applications.autoconfigured-tests" target="_blank" rel="noreferrer noopener">configuring the &#8220;slice&#8221;</a> of the system to test, as it reduces a lot of copy-and-paste code.</p>



<p class="wp-block-paragraph">Another possible solution would be to create a base class and making each test extend it. However, <a href="https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)#Issues_and_alternatives" target="_blank" rel="noreferrer noopener">inheritance comes with a lot of issues</a> that I don&#8217;t want to deal with just to provide a common configuration for some tests.</p>



<p class="wp-block-paragraph">A custom annotation that encloses all the common configurations for tests is both an elegant and simple solution. In the following example, instead of annotating my tests with <code>@WebMvcTest</code> and <code>@Import</code>, I&#8217;m going to create <code>@RestControllerIntegrationTest</code> which will take care of all the configuration details. Thanks to this, I will avoid duplicating the code or complicating it with unnecessary inheritance.</p>



<h2 class="wp-block-heading">Create a custom annotation for MVC tests</h2>



<p class="wp-block-paragraph">First, I&#8217;m going to replace the <code>@WebMvcTest</code> annotation with a custom one. I&#8217;m going to create the following <code>RestControllerIntegrationTest</code> annotation:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.testing.annotations;

import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.ContextConfiguration;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@WebMvcTest
public @interface RestControllerIntegrationTest {

    /**
     * @see WebMvcTest#value
     */
    @AliasFor(annotation = WebMvcTest.class, attribute = "value")
    Class&lt;?&gt;[] value() default {};

    /**
     * @see WebMvcTest#controllers
     */
    @AliasFor(annotation = WebMvcTest.class, attribute = "controllers")
    Class&lt;?&gt;[] controllers() default {};
}</pre></div>



<p class="wp-block-paragraph">Let&#8217;s take a look at the annotations I&#8217;m using here:</p>



<ol class="wp-block-list"><li><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/Retention.html" target="_blank" rel="noreferrer noopener">@Retention</a> –&nbsp;specifies how long an annotation is to be retained. The <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/RetentionPolicy.html#RUNTIME" target="_blank" rel="noreferrer noopener">RUNTIME</a> Retention Policy enables the annotation to be retained by the VM at run time.</li><li><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/Target.html" target="_blank" rel="noreferrer noopener">@Target</a> – puts constrains on the usage of the annotation. The <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/ElementType.html#TYPE" target="_blank" rel="noreferrer noopener">TYPE</a> Element Type will allow using it on my test classes.</li><li><a href="https://docs.spring.io/spring-boot/docs/2.6.4/api/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.html" target="_blank" rel="noreferrer noopener">@WebMvcTest</a> – since I am creating my own annotation for MVC tests, i need to include this Spring Boot annotation to still benefit from all the default features.</li></ol>



<p class="wp-block-paragraph">Thus, I can now replace <code>@WebMvcTest</code> with <code>@RestControllerIntegrationTest</code> and still have the same functionality:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.products.adapters.driving.api.http.controllers;

import in.keepgrowing.keycloakspringboot.testing.annotations.RestControllerIntegrationTest;
…
@RestControllerIntegrationTest(value = ProductController.class)
class ProductControllerTest {
…</pre></div>



<p class="wp-block-paragraph">Now, I can add any additional configuration my test &#8220;slice&#8221; requires to the custom annotation.</p>



<h2 class="wp-block-heading">Provide additional configuration</h2>



<p class="wp-block-paragraph">In <a href="https://github.com/little-pinecone/keycloak-spring-boot" target="_blank" rel="noreferrer noopener">my example project</a>, I&#8217;m using the <code>@PreAuthorize</code> annotation to restrict user access to the API endpoints. Therefore, I need to enable <a href="https://docs.spring.io/spring-security/reference/servlet/authorization/method-security.html" target="_blank" rel="noreferrer noopener">method-level security</a>. Without it, the following test fails because it is missing the configuration required to apply the appropriate access control:</p>



<div class="wp-block-image"><figure class="aligncenter size-full is-resized"><img decoding="async" src="https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests.webp" alt="Spring test failing without annotation" class="wp-image-9793" width="750" height="58" srcset="https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests.webp 1000w, https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests-300x23.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests-768x59.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests-700x54.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests-520x40.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests-360x28.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests-250x19.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/03/failing-tests-100x8.webp 100w" sizes="(max-width: 750px) 100vw, 750px" /></figure></div>



<p class="wp-block-paragraph">For that reason, I&#8217;m going to create a configuration class and annotate it with <a href="https://docs.spring.io/spring-security/site/docs/5.6.0-M1/api/org/springframework/security/config/annotation/method/configuration/EnableMethodSecurity.html" target="_blank" rel="noreferrer noopener">@EnableMethodSecurity</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.testing.config;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;

@TestConfiguration
@EnableMethodSecurity
public class ControllerIntegrationTestConfig {
}</pre></div>



<p class="wp-block-paragraph">Next, I&#8217;ll load it into <code>ApplicationContext</code> using <a href="https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/ContextConfiguration.html" target="_blank" rel="noreferrer noopener">@ContextConfiguration</a> in my custom annotation:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.testing.annotations;

import in.keepgrowing.keycloakspringboot.testing.config.ControllerIntegrationTestConfig;
…
@ContextConfiguration(classes = ControllerIntegrationTestConfig.class)
public @interface RestControllerIntegrationTest {</pre></div>



<h3 class="wp-block-heading">Verify results</h3>



<p class="wp-block-paragraph">As a result, all tests in classes annotated with <code>@RestControllerIntegrationTest</code> will be able to use method-level security. The following screenshot shows that my tests are passing now:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img decoding="async" width="360" height="183" src="https://keepgrowing.in/wp-content/uploads/2022/03/passing-tests.webp" alt="passing tests with custom annotation" class="wp-image-9792" srcset="https://keepgrowing.in/wp-content/uploads/2022/03/passing-tests.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/03/passing-tests-300x153.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/03/passing-tests-250x127.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/03/passing-tests-100x51.webp 100w" sizes="(max-width: 360px) 100vw, 360px" /></figure></div>



<h2 class="wp-block-heading">Read more about setting up tests in Spring Boot</h2>



<ul class="wp-block-list"><li><a href="https://www.wimdeblauwe.com/blog/2020/04/17/spring-boot-test-slices-with-custom-annotations/" target="_blank" rel="noreferrer noopener">Spring Boot test slices with custom annotations</a></li><li><a href="https://github.com/ch4mpy/spring-addons/issues/2" target="_blank" rel="noreferrer noopener">Document how to use this if Keycloak is on the classpath</a></li><li><a href="https://keepgrowing.in/tag/testing/" target="_blank" rel="noreferrer noopener">My other posts regarding testing</a></li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@georgia-maciel-1033378?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Georgia Maciel</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/girl-holding-ice-cream-2168801/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/java/springboot/create-a-custom-annotation-to-configure-spring-boot-tests/">Create a custom annotation to configure Spring Boot tests</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/java/springboot/create-a-custom-annotation-to-configure-spring-boot-tests/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">9707</post-id>	</item>
		<item>
		<title>Keycloak with Spring Boot #4 – Simple guide for roles and authorities</title>
		<link>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-4-simple-guide-for-roles-and-authorities/</link>
					<comments>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-4-simple-guide-for-roles-and-authorities/#respond</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Sun, 27 Feb 2022 13:44:36 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[user management]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=8215</guid>

					<description><![CDATA[<p>Delegating user management to Keycloak allows us to better focus on meeting the business needs of an application. However, we still need to provide the appropriate configuration to translate user roles and privileges between Keycloak and Spring Boot. Additionally, we&#8217;re going to need some handy techniques for debugging how roles are converted between the two services. Prerequisities The main principles of managing roles in Keycloak are described in the Keycloak in Docker #4 – How to define user privileges and roles post. Furthermore, you can follow the&#160;Keycloak with Spring Boot #1 –&#160;Configure Spring Security with Keycloak&#160;post to recreate the example configuration I use in this article. First, I will describe some debugging techniques. Next, I&#8217;ll show you some sample role mapping setups. Debugging role mapping between Keycloak and Spring Boot I&#8217;m going to show you some useful methods for verifying role support in a Spring Boot app and Keycloak server. By seeing what is really going on under the hood, you can save a lot of time when an apparently correct configuration does not bring the expected results. How to debug roles in Spring Security Context We can look into the Spring Security Context to verify the actual permissions that are being assessed in two ways: Set the security logging level to DEBUG – add the logging.level.org.springframework.security=DEBUG property to the application.properties file. Thanks to this, after each API request you&#8217;ll see a list of Granted Authorities in the logs: Log Authorities manually – if you only want to log authorities for a single request, you can obtain Authentication from Security Context Holder and log GrantedAuthorities directly inside a selected endpoint: As a result, when you call this endpoint, you&#8217;ll see log entries similar to these: How to debug roles sent from Keycloak In my example realm, there is a default user christina who has the roles of user and chief-operation-officer. We can verify her privileges by copying the token from Postman or from the developer tool in the browser as seen in the screenshots below: Then, decode the token value in e.g. jwt.io tool to see the actual content: Roles vs Authorities Spring Security allows us to configure privileges in a very granular manner with Authorities (e.g. CAN_WRITE). However, we can also manage resource access in a more coarse fashion with Roles (e.g ROLE_EDITOR). In other words, the ROLE_ prefix is what differentiate these concepts in Spring. Keycloak recognises this naming convention. Therefore, we can decide whether we want to map privileges defined in our Keycloak server as roles or authorities in Spring Boot. Mapping Roles To map my chief-operating-officer Keycloak role to ROLE_CHIEF-OPERATING-OFFICER in Spring Boot, I&#8217;m going to use SimpleAuthorityMapper: As we can see in the SimpleAuthorityMapper documentation, the default prefix is ROLE_: Therefore, we don&#8217;t need to set it manually. As a result, I can impose access restrictions to selected resources. Below you can see the role used in the @PreAuthorize annotation: On the other hand, I can restrict access to all POST endpoints only to users with this role: In both cases, the hasRole expression will automatically add the ROLE_ prefix to the given CHIEF-OPERATING-OFFICER value and compare the result with the ROLE_CHIEF-OPERATING-OFFICER GrantedAuthority value which we have mapped in the Spring SecurityContext. This behaviour is described in the method docs: Mapping Authorities If you want to control access in more detail, you can map the permissions from Keycloak to Authorities in Spring Security. Remove the ROLE_ prefix when configuring the authority mapper: This makes the sample can-write permission from Keycloak become CAN-WRITE authority in Spring SecurityContext. Below you can see the authority used in the @PreAuthorize annotation: Then again, I can restrict access to all POST endpoints only to users with this authority: In both cases, the hasAuthority expression will compare the given CAN-WRITE value with the CAN-WRITE GrantedAuthority value which we have mapped in the Spring SecurityContext. If you configure the authority mapper in a way that removes the ROLE_ prefix from the authorities, don&#8217;t use hasRole in security expressions and configuration. Realm roles vs client roles You can read about differences between the realm and client roles in the Keycloak in Docker #4 – How to define user privileges and roles article. Given that the Keycloak server contains properly defined user roles, we need to instruct our Spring Boot app which role set to evaluate. We&#8217;ll do so with the keycloak.use-resource-role-mappings property. Evaluate realm roles in Spring Boot A Spring Boot app will evaluate the realm roles if the keycloak.use-resource-role-mappings property is set to false, which is the default value. You can verify that the values from the realm-access field in the access token are present as GrantedAuthirities in the SecurityContext using the debug methods shown above. Evaluate client roles in Spring Boot In the keycloak.* properties, resource is the client. Therefore, by setting keycloak.use-resource-role-mappings to true, we&#8217;re telling Spring Boot that the client roles should be considered. You can verify that the values from the resource-access field in the access token are present as GrantedAuthirities in the SecurityContext using the debug methods shown above. Handle user roles in Spring Boot tests When we restrict endpoint access to a specific role, we need to update Spring MVC tests to keep them working properly. Custom annotation for a mocked user Fortunately, Spring provides us with the @WithMockUser annotation that allows us to test an endpoint for a given user role, e.g.: In the same manner we can mock a test user with a given authority: However, having to manually enter a role name for each test case or test class where that role matters would be cumbersome. Instead, we can create a custom meta annotation: And then use it in test cases (or classes) like in the example snippet below: Enable method-level security If we&#8217;re using annotations like @PreAuthorize to restrict access to endpoints, we have to create an appropriate configuration class for our MVC tests: Then we have to load it when running the tests. We can achieve it by adding @Import or [&#8230;]</p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-4-simple-guide-for-roles-and-authorities/">Keycloak with Spring Boot #4 – Simple guide for roles and authorities</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Delegating user management to Keycloak allows us to better focus on meeting the business needs of an application. However, we still need to provide the appropriate configuration to translate user roles and privileges between Keycloak and Spring Boot. Additionally, we&#8217;re going to need some handy techniques for debugging how roles are converted between the two services.</p>



<span id="more-8215"></span>



<h2 class="wp-block-heading" id="prerequisities">Prerequisities</h2>



<ul class="wp-block-list"><li>The main principles of managing roles in Keycloak are described in the <a href="https://keepgrowing.in/tools/keycloak-in-docker-4-how-to-define-user-privileges-and-roles/" target="_blank" rel="noreferrer noopener">Keycloak in Docker #4 – How to define user privileges and roles</a> post.</li><li>Furthermore, you can follow the&nbsp;<a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/" target="_blank" rel="noreferrer noopener">Keycloak with Spring Boot #1 –&nbsp;Configure Spring Security with Keycloak</a>&nbsp;post to recreate the example configuration I use in this article.</li></ul>



<p class="wp-block-paragraph">First, I will describe some debugging techniques. Next, I&#8217;ll show you some sample role mapping setups.</p>



<h2 class="wp-block-heading" id="how-to-debug-authorities-in-spring-boot">Debugging role mapping between Keycloak and Spring Boot</h2>



<p class="wp-block-paragraph">I&#8217;m going to show you some useful methods for verifying role support in a Spring Boot app and Keycloak server. By seeing what is really going on under the hood, you can save a lot of time when an apparently correct configuration does not bring the expected results.</p>



<h3 class="wp-block-heading" id="how-to-debug-authorities-in-spring-boot">How to debug roles in Spring Security Context</h3>



<p class="wp-block-paragraph">We can look into the Spring Security Context to verify the actual permissions that are being assessed in two ways:</p>



<ul class="wp-block-list"><li>Set the security logging level to <code>DEBUG</code> – add the <code>logging.level.org.springframework.security=DEBUG</code> property to the <code>application.properties</code> file. Thanks to this, after each API request you&#8217;ll see a list of <code>Granted Authorities</code> in the logs:</li></ul>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">DEBUG --- w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=KeycloakAuthenticationToken [Principal=…, Granted Authorities=[ROLE_chief-operating-officer, ROLE_user]]] to HttpSession</pre></div>



<ul class="wp-block-list"><li>Log <a href="https://docs.spring.io/spring-security/reference/servlet/authorization/architecture.html" target="_blank" rel="noreferrer noopener">Authorities</a> manually – if you only want to log authorities for a single request, you can obtain <a href="https://docs.spring.io/spring-security/reference/servlet/authentication/index.html" target="_blank" rel="noreferrer noopener">Authentication</a> from <a href="https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-securitycontextholder" target="_blank" rel="noreferrer noopener">Security Context Holder</a> and log <a href="https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-granted-authority" target="_blank" rel="noreferrer noopener">GrantedAuthorities</a> directly inside a selected endpoint:</li></ul>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.products.adapters.driving.api.http.controllers;

import in.keepgrowing.keycloakspringboot.products.adapters.driving.api.http.model.responses.ProductResponse;
import in.keepgrowing.keycloakspringboot.products.adapters.driving.api.http.services.ProductHttpApiFacade;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import java.util.List;
…
@RestController
@RequestMapping(value = ProductControllerPaths.PRODUCTS_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
@Log4j2
public class ProductController {
    …
    @GetMapping
    public ResponseEntity&lt;List&lt;ProductResponse&gt;&gt; findAll() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        auth.getAuthorities().forEach(a-&gt;log.info(String.valueOf(a)));

        return new ResponseEntity&lt;&gt;(apiFacade.findAll(), HttpStatus.OK);
    }
…</pre></div>



<p class="wp-block-paragraph">As a result, when you call this endpoint, you&#8217;ll see log entries similar to these:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">INFO --- i.k.s.p.p.controllers.ProductController  : ROLE_CHIEF-OPERATING-OFFICER
INFO --- i.k.s.p.p.controllers.ProductController  : ROLE_USER</pre></div>



<h3 class="wp-block-heading" id="how-to-debug-roles-sent-from-keycloak">How to debug roles sent from Keycloak</h3>



<p class="wp-block-paragraph">In my example realm, there is a default user <code>christina</code> who has the roles of <code>user</code> and <code>chief-operation-officer</code>. We can verify her privileges by copying the <a href="https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/" target="_blank" rel="noreferrer noopener">token from Postman</a> or from the developer tool in the browser as seen in the screenshots below:</p>



<figure class="wp-block-gallery has-nested-images columns-2 wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="760" height="232" data-id="9646" src="https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman.webp" alt="token with Keycloak roles in Postman and browser debug tool" class="wp-image-9646" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman.webp 760w, https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman-300x92.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman-700x214.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman-520x159.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman-360x110.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman-250x76.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/token-in-postman-100x31.webp 100w" sizes="auto, (max-width: 760px) 100vw, 760px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1343" height="582" data-id="8246" src="https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger.png" alt="token in a browser debugger" class="wp-image-8246" srcset="https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger.png 1343w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-300x130.png 300w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-1024x444.png 1024w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-768x333.png 768w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-700x303.png 700w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-520x225.png 520w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-360x156.png 360w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-250x108.png 250w, https://keepgrowing.in/wp-content/uploads/2021/12/Bearer-token-from-debugger-100x43.png 100w" sizes="auto, (max-width: 1343px) 100vw, 1343px" /></figure>
</figure>



<p class="wp-block-paragraph">Then, decode the token value in e.g. <a href="http://jwt.io" target="_blank" rel="noreferrer noopener">jwt.io</a> tool to see the actual content:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="825" height="445" src="https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles.webp" alt="token with user roles from Kecyloak" class="wp-image-9591" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles.webp 825w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-300x162.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-768x414.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-700x378.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-520x280.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-360x194.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-250x135.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-100x54.webp 100w" sizes="auto, (max-width: 825px) 100vw, 825px" /></figure>



<h2 class="wp-block-heading" id="how-to-map-keycloak-roles-to-spring-security-standard">Roles vs Authorities</h2>



<p class="wp-block-paragraph">Spring Security allows us to configure privileges in a very granular manner with Authorities (e.g. CAN_WRITE). However, we can also manage resource access in a more coarse fashion with Roles (e.g ROLE_EDITOR). In other words, the ROLE_ prefix is what differentiate these concepts in Spring.</p>



<p class="wp-block-paragraph">Keycloak <a href="https://www.keycloak.org/docs/16.1/securing_apps/#naming-security-roles" target="_blank" rel="noreferrer noopener">recognises this naming convention</a>. Therefore, we can decide whether we want to map privileges defined in our Keycloak server as roles or authorities in Spring Boot.</p>



<h3 class="wp-block-heading">Mapping Roles</h3>



<p class="wp-block-paragraph">To map my <code>chief-operating-officer</code> Keycloak role to <code>ROLE_CHIEF-OPERATING-OFFICER</code> in Spring Boot, I&#8217;m going to use <a href="https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.html" target="_blank" rel="noreferrer noopener">SimpleAuthorityMapper</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;

@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
    …
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(getKeycloakAuthenticationProvider());
    }

    private KeycloakAuthenticationProvider getKeycloakAuthenticationProvider() {
        KeycloakAuthenticationProvider authenticationProvider = keycloakAuthenticationProvider();
        var mapper = new SimpleAuthorityMapper();
        mapper.setConvertToUpperCase(true);
        authenticationProvider.setGrantedAuthoritiesMapper(mapper);

        return authenticationProvider;
    }
    …
}</pre></div>



<div class="wp-block-urvanov-syntax-highlighter-code-block"></div>



<p class="wp-block-paragraph">As we can see in the <code>SimpleAuthorityMapper</code> documentation, the default prefix is <code>ROLE_</code>:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="859" height="344" src="https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code.png" alt="Documentation of role mapper from Spring used by Keycloak" class="wp-image-8260" srcset="https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code.png 859w, https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code-300x120.png 300w, https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code-768x308.png 768w, https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code-700x280.png 700w, https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code-520x208.png 520w, https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code-360x144.png 360w, https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code-250x100.png 250w, https://keepgrowing.in/wp-content/uploads/2021/12/simple-authority-mapper-code-100x40.png 100w" sizes="auto, (max-width: 859px) 100vw, 859px" /></figure></div>



<p class="wp-block-paragraph">Therefore, we don&#8217;t need to set it manually.</p>



<p class="wp-block-paragraph">As a result, I can impose access restrictions to selected resources. Below you can see the role used in the <a href="https://docs.spring.io/spring-security/site/docs/5.7.x/api/org/springframework/security/access/prepost/package-summary.html" target="_blank" rel="noreferrer noopener">@PreAuthorize</a> annotation:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootswaggeruikeycloak.products.presentation.controllers;

import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
…
public class ProductController {
    …
    @PostMapping()
    @PreAuthorize("hasRole('CHIEF-OPERATING-OFFICER')")
    public ResponseEntity&lt;Product&gt; save(@RequestBody Product productDetails) {
        …
    }
}</pre></div>



<p class="wp-block-paragraph">On the other hand, I can restrict access to all POST endpoints only to users with this role:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
…

@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
…
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
                …
                .antMatchers(HttpMethod.POST).hasRole("CHIEF-OPERATING-OFFICER")
                …
    }
…</pre></div>



<p class="wp-block-paragraph">In both cases, the <code>hasRole</code> expression will automatically add the <code>ROLE_</code> prefix to the given <code>CHIEF-OPERATING-OFFICER</code> value and compare the result with the <code>ROLE_CHIEF-OPERATING-OFFICER</code> <code>GrantedAuthority</code> value which we have mapped in the Spring <code>SecurityContext</code>. This behaviour is described in the method docs:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="658" height="264" src="https://keepgrowing.in/wp-content/uploads/2021/12/expression-url-authorization-configurer-code.png" alt="Spring Boot method for evaluating user role" class="wp-image-8266" srcset="https://keepgrowing.in/wp-content/uploads/2021/12/expression-url-authorization-configurer-code.png 658w, https://keepgrowing.in/wp-content/uploads/2021/12/expression-url-authorization-configurer-code-300x120.png 300w, https://keepgrowing.in/wp-content/uploads/2021/12/expression-url-authorization-configurer-code-520x209.png 520w, https://keepgrowing.in/wp-content/uploads/2021/12/expression-url-authorization-configurer-code-360x144.png 360w, https://keepgrowing.in/wp-content/uploads/2021/12/expression-url-authorization-configurer-code-250x100.png 250w, https://keepgrowing.in/wp-content/uploads/2021/12/expression-url-authorization-configurer-code-100x40.png 100w" sizes="auto, (max-width: 658px) 100vw, 658px" /></figure></div>



<h3 class="wp-block-heading">Mapping Authorities</h3>



<p class="wp-block-paragraph">If you want to control access in more detail, you can map the permissions from Keycloak to <code>Authorities</code> in Spring Security. Remove the <code>ROLE_</code> prefix when configuring the authority mapper:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;
…
    private KeycloakAuthenticationProvider getKeycloakAuthenticationProvider() {
        KeycloakAuthenticationProvider authenticationProvider = keycloakAuthenticationProvider();
        var mapper = new SimpleAuthorityMapper();
        mapper.setConvertToUpperCase(true);
        mapper.setPrefix("");
        authenticationProvider.setGrantedAuthoritiesMapper(mapper);

        return authenticationProvider;
    }
    …</pre></div>



<p class="wp-block-paragraph">This makes the sample <code>can-write</code> permission from Keycloak become <code>CAN-WRITE</code> authority in Spring SecurityContext.</p>



<p class="wp-block-paragraph">Below you can see the authority used in the <a href="https://docs.spring.io/spring-security/site/docs/5.7.x/api/org/springframework/security/access/prepost/package-summary.html" target="_blank" rel="noreferrer noopener">@PreAuthorize</a> annotation:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootswaggeruikeycloak.products.presentation.controllers;

import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
…
public class ProductController {
    …
    @PostMapping()
    @PreAuthorize("hasAuthority('CAN-WRITE')")
    public ResponseEntity&lt;Product&gt; save(@RequestBody Product productDetails) {
        …
    }
}</pre></div>



<p class="wp-block-paragraph">Then again, I can restrict access to all POST endpoints only to users with this authority:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
…

@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
…
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
                …
                .antMatchers(HttpMethod.POST).hasAuthority(("CAN-WRITE")
                …
    }
…</pre></div>



<p class="wp-block-paragraph">In both cases, the <code>hasAuthority</code> expression will compare the given <code>CAN-WRITE</code> value with the <code>CAN-WRITE</code> <code>GrantedAuthority</code> value which we have mapped in the Spring <code>SecurityContext</code>.</p>



<p class="wp-block-paragraph">If you configure the authority mapper in a way that removes the <code>ROLE_</code> prefix from the authorities, don&#8217;t use <code>hasRole</code> in security expressions and configuration. </p>



<h2 class="wp-block-heading" id="how-to-map-keycloak-roles-to-spring-security-standard">Realm roles vs client roles</h2>



<p class="wp-block-paragraph">You can read about differences between the realm and client roles in the <a href="https://keepgrowing.in/tools/keycloak-in-docker-4-how-to-define-user-privileges-and-roles/" target="_blank" rel="noreferrer noopener">Keycloak in Docker #4 – How to define user privileges and roles</a> article. Given that the Keycloak server contains properly defined user roles, we need to instruct our Spring Boot app which role set to evaluate. We&#8217;ll do so with the <code>keycloak.use-resource-role-mappings</code> property.</p>



<h3 class="wp-block-heading" id="how-to-map-keycloak-roles-to-spring-security-standard">Evaluate realm roles in Spring Boot</h3>



<p class="wp-block-paragraph">A Spring Boot app will evaluate the realm roles if the <code>keycloak.use-resource-role-mappings</code> property is set to <code>false</code>, which is the <strong>default</strong> value. You can verify that the values from the <code>realm-access</code> field in the access token are present as <code>GrantedAuthirities</code> in the <code>SecurityContext</code> using the debug methods shown above.</p>



<h3 class="wp-block-heading" id="how-to-map-keycloak-roles-to-spring-security-standard">Evaluate client roles in Spring Boot</h3>



<p class="wp-block-paragraph">In the <code>keycloak.*</code> properties, <code>resource</code> is the <code>client</code>. Therefore, by setting <code>keycloak.use-resource-role-mappings</code> to <code>true</code>, we&#8217;re telling Spring Boot that the client roles should be considered. You can verify that the values from the <code>resource-access</code> field in the access token are present as <code>GrantedAuthirities</code> in the <code>SecurityContext</code> using the debug methods shown above.</p>



<h2 class="wp-block-heading" id="read-more-on-handling-the-role-prefix-with-spring-security-grantedauthoritiesmapper">Handle user roles in Spring Boot tests</h2>



<p class="wp-block-paragraph">When we restrict endpoint access to a specific role, we need to update Spring MVC tests to keep them working properly.</p>



<h3 class="wp-block-heading">Custom annotation for a mocked user</h3>



<p class="wp-block-paragraph">Fortunately, Spring provides us with the <a href="https://docs.spring.io/spring-security/reference/servlet/test/method.html#test-method-withmockuser" target="_blank" rel="noreferrer noopener">@WithMockUser</a> annotation that allows us to test an endpoint for a given user role, e.g.:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.products.adapters.driving.api.http.controllers;

import org.springframework.security.test.context.support.WithMockUser;
…
@Test
@WithMockUser(roles="CHIEF-OPERATING-OFFICER")
void shouldDeleteProduct() throws Exception {
    mvc.perform(delete(BASE_PATH + "/" + TEST_UUID)
                    .contentType(MediaType.APPLICATION_JSON)
                    .with(csrf()))
            .andExpect(status().isNoContent());
}</pre></div>



<p class="wp-block-paragraph">In the same manner we can mock a test user with a given authority:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
@WithMockUser(authorities="CAN-WRITE")
…</pre></div>



<p class="wp-block-paragraph">However, having to manually enter a role name for each test case or test class where that role matters would be cumbersome. Instead, we can create a custom <a href="https://docs.spring.io/spring-security/reference/servlet/test/method.html#test-method-meta-annotations" target="_blank" rel="noreferrer noopener">meta annotation</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.testing.annotations;

import org.springframework.security.test.context.support.WithMockUser;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@WithMockUser(roles="CHIEF-OPERATING-OFFICER")
public @interface WithMockChiefOperationOfficer {
}</pre></div>



<p class="wp-block-paragraph">And then use it in test cases (or classes) like in the example snippet below:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.products.adapters.driving.api.http.controllers;

import in.keepgrowing.keycloakspringboot.testing.annotations.WithMockChiefOperationOfficer;
…
@Test
@WithMockChiefOperationOfficer
void shouldDeleteProduct() throws Exception {
…</pre></div>



<h3 class="wp-block-heading">Enable method-level security</h3>



<p class="wp-block-paragraph">If we&#8217;re using annotations like <code>@PreAuthorize</code> to restrict access to endpoints, we have to create an appropriate configuration class for our MVC tests:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.testing.config;
 
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
 
@TestConfiguration
@EnableMethodSecurity
public class ControllerIntegrationTestConfig {
}</pre></div>



<p class="wp-block-paragraph">Then we have to load it when running the tests. We can achieve it by adding <a href="https://docs.spring.io/spring-boot/docs/2.6.4/reference/htmlsingle/#using.configuration-classes.importing-additional-configuration" target="_blank" rel="noreferrer noopener">@Import</a> or <a href="https://keepgrowing.in/java/springboot/create-a-custom-annotation-to-configure-spring-boot-tests/" target="_blank" rel="noreferrer noopener"> a custom annotation</a> to the test classes.</p>



<h2 class="wp-block-heading" id="read-more-on-handling-the-role-prefix-with-spring-security-grantedauthoritiesmapper">Read more on handling Keycloak roles in Spring Boot</h2>



<ul class="wp-block-list"><li><a href="https://stackoverflow.com/a/19542316/7995881" target="_blank" rel="noreferrer noopener">Difference between Role and GrantedAuthority in Spring Security</a></li><li><a href="https://stackoverflow.com/questions/33205236/spring-security-added-prefix-role-to-all-roles-name" target="_blank" rel="noreferrer noopener">Spring security added prefix &#8220;ROLE_&#8221; to all roles name?</a></li><li><a href="https://github.com/spring-projects/spring-security/blob/main/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.java" target="_blank" rel="noreferrer noopener">SimpleAuthorityMapper.java</a> in the GitHub repo</li><li><a href="https://docs.spring.io/spring-boot/docs/2.6.4/reference/htmlsingle/#howto.testing.with-spring-security" target="_blank" rel="noreferrer noopener">Testing With Spring Security</a></li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@robert-nagy-512974?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Robert Nagy</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/woman-buying-a-drink-3991987/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-4-simple-guide-for-roles-and-authorities/">Keycloak with Spring Boot #4 – Simple guide for roles and authorities</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-4-simple-guide-for-roles-and-authorities/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8215</post-id>	</item>
		<item>
		<title>Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI</title>
		<link>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/</link>
					<comments>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/#comments</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Thu, 24 Feb 2022 10:48:07 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[OpenAPI]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[Swagger UI]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=8314</guid>

					<description><![CDATA[<p>Swagger offers various methods to authorize requests to our Keycloak secured API. I&#8217;ll show you how to implement the recommended grant types and why certain flows are advised against in the OAuth 2.0 specification. Prerequisites The security configuration for Keycloak is described in the Keycloak with Spring Boot #1 –&#160;Configure Spring Security with Keycloak post. You&#8217;ll need Swagger UI in your project. I&#8217;m using the springdoc-openapi dependency in my example: As a result, I have Swagger UI at http://localhost:8080/swagger-ui.html and OpenAPI specification at http://localhost:8080/v3/api-docs. For more information on documenting Spring Boot applications using Springdoc, see the Easy OpenAPI 3 specification for your Spring Boot REST API article. Authorize Swagger requests in Keycloak I&#8217;ll demonstrate three authorization configurations: Authorization Code which is one of the OAuth 2.0 flows, OpenID Connect Discovery mechanism, Bearer Authentication. Select the one that better suits the needs of your project. In the end, we want to end up with the Authorize button that will provide authorization options suitable for our API and Keycloak server: Allow access to Swagger endpoints I&#8217;m going to modify my SecurityConfig class to allow Swagger endpoints to be called without authentication: Provide Keycloak server details Authorizatin Code and OpenID Connect Disvovery require realm name and the url of the Keycloak server for proper configuration. Although we can provide them as hardcoded strings for testing purposes, I&#8217;m going to reuse the data that&#8217;s already available in my application.properties file: To access the properties in the code, I&#8217;m going to create the following short record: That&#8217;s all we need to inject these properties into our Swagger config if our project uses a Java version with Record support. Alternatively, follow the Type-safe Configuration Properties::Constructor Binding section in the Spring docs to use a simple class (with getters and @ConstructorBinding annotation). Thanks to this, I only provide Keycloak details in one place and I don&#8217;t have to painstakingly search my configuration classes to update the values. Additionally, the properties will always be in accordance with the selected application profile (dev, production, etc.). Swagger authorization with the OAuth 2.0 protocol The example implementation is available in the keycloak-spring-boot repository. First of all, I&#8217;m going to consult the Swagger docs for a quick summary of the authorization flows available: The&#160;flows&#160;(also called&#160;grant types) are scenarios an API client performs to get an access token from the authorization server. OAuth 2.0 provides several flows suitable for different types of API clients:&#8211; Authorization code,&#8211; Implicit,&#8211; Resource owner password credentials,&#8211; Client credentials. https://swagger.io/docs/specification/authentication/oauth2/ I&#8217;m going to provide the configuration for the Authorization Code Grant as this is the most secure option for my Swagger API calls. The following quote contains a brief explanation of this flow: When the user authorizes the application, they are redirected back to the application with a temporary code in the URL. The application exchanges that code for the access token. When the application makes the request for the access token, that request can be authenticated with the client secret, which reduces the risk of an attacker intercepting the authorization code and using it themselves. This also means the access token is never visible to the user or their browser, so it is the most secure way to pass the token back to the application, reducing the risk of the token leaking to someone else. https://www.oauth.com/oauth2-servers/server-side-apps/authorization-code/ Make sure that the Standard Flow is enabled in Keycloak as it allows us to use the Authorization Code flow: Configuration class Let&#8217;s look at the example configuration documented in Swagger: In other words, in order to authorize requests in Keycloak, Swagger requires a component containing a security scheme with a particular flow. Based on this, I can provide my own setup in Java. Below you can see the full configuration class: There are a few things to note: Components – a collection of reusable objects that define various aspects of the Open API Specification. SecuritySceme – here we can define our scheme type with the Authorization Code flow. OAuthflow – an object for specifying the configuration details of the selected flow. We have to follow the list of the required fields for each auth type from the screenshot below: As a result, we&#8217;ll see that the Authiorization Code Grant will be the only available auth option in Swagger UI: Adding Scopes to the config In the screenshot with required fields for the OAuth flow, we can read that scopes field is just a map between their names and descriptions: Therefore, if you want to provide a scope, e.g. address, you need to add it when creating the authorization flow: As a consequence, the list of scopes will appear in the Swagger authorization window after restarting the application: Another thing to remember is that if you don&#8217;t add the openid scope, you&#8217;ll get the following warning in the keycloak instance&#8217;s logs: As a result, the requests are still valid OAuth2 requests. However, the behaviour might be unpredictable if you rely on the OIDC standard. Swagger authorization with the OpenID Connect Discovery mechanism The example implementation is available in the spring-boot-swagger-ui-keycloak repository. If you need more security schemes available in Swagger UI, you can easily achieve it with the OIDC discovery mechanism. It takes advantage of the fact that the OpenID server publishes its metadata to a well-known url: This specification defines a mechanism for an OpenID Connect Relying Party to discover the End-User&#8217;s OpenID Provider and obtain information needed to interact with it, including its OAuth 2.0 endpoint locations. https://openid.net/specs/openid-connect-discovery-1_0.html In order to find the correct endpoint for your Keycloak realm, select the OpenID Endpoint Configuration option in the realm settings: In other words, the http://localhost:8024/auth/realms/keep-growing/.well-known/openid-configuration url contains the data required by the discovery mechanism to identify all available authorization schemes: Configuration class Let&#8217;s look at the example configuration documented in Swagger: The config for this security scheme is very short because all necessary information will be automatically acquired form the OpenID configuration endpoint: As a result, I will see all the available authorizations in my Swagger UI: Swagger authorization with bearer [&#8230;]</p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/">Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Swagger offers various methods to authorize requests to our Keycloak secured API. I&#8217;ll show you how to implement the recommended grant types and why certain flows are advised against in the OAuth 2.0 specification.</p>



<span id="more-8314"></span>



<h2 class="wp-block-heading" id="prerequisites">Prerequisites</h2>



<ul class="wp-block-list"><li>The security configuration for Keycloak is described in the <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/" target="_blank" rel="noreferrer noopener">Keycloak with Spring Boot #1 –&nbsp;Configure Spring Security with Keycloak</a> post.</li><li>You&#8217;ll need Swagger UI in your project. I&#8217;m using the <a href="https://springdoc.org/" target="_blank" rel="noreferrer noopener">springdoc-openapi</a> dependency in my example:</li></ul>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">&lt;!-- pom.xml --&gt;
…	
&lt;properties&gt;
    …
    &lt;springdoc.version&gt;1.6.6&lt;/springdoc.version&gt;
&lt;/properties&gt;
…
&lt;dependencies&gt;
    …
    &lt;dependency&gt;
        &lt;groupId&gt;org.springdoc&lt;/groupId&gt;
        &lt;artifactId&gt;springdoc-openapi-ui&lt;/artifactId&gt;
        &lt;version&gt;${springdoc.version}&lt;/version&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;
…</pre></div>



<p class="wp-block-paragraph">As a result, I have Swagger UI at <a href="http://localhost:8080/swagger-ui.html" target="_blank" rel="noreferrer noopener">http://localhost:8080/swagger-ui.html</a> and OpenAPI specification at <a href="http://localhost:8080/v3/api-docs" target="_blank" rel="noreferrer noopener">http://localhost:8080/v3/api-docs</a>. For more information on documenting Spring Boot applications using Springdoc, see the <a href="https://keepgrowing.in/java/springboot/easy-openapi-3-specification-for-your-spring-boot-api/" target="_blank" rel="noreferrer noopener">Easy OpenAPI 3 specification for your Spring Boot REST API</a> article.</p>



<h2 class="wp-block-heading" id="more-on-how-to-authorize-requests-from-swagger-ui-in-keycloak">Authorize Swagger requests in Keycloak</h2>



<p class="wp-block-paragraph">I&#8217;ll demonstrate three authorization configurations:</p>



<ul class="wp-block-list"><li><code>Authorization Code</code> which is one of the OAuth 2.0 flows,</li><li><code>OpenID Connect Discovery</code> mechanism,</li><li><code>Bearer Authentication</code>.</li></ul>



<p class="wp-block-paragraph">Select the one that better suits the needs of your project. In the end, we want to end up with the <code>Authorize</code> button that will provide authorization options suitable for our API and Keycloak server:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1005" height="556" src="https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button.webp" alt="Authorize button in Swagger that will work with Keycloak" class="wp-image-9558" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button.webp 1005w, https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button-300x166.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button-768x425.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button-700x387.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button-520x288.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button-360x199.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button-250x138.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/authorize-button-100x55.webp 100w" sizes="auto, (max-width: 1005px) 100vw, 1005px" /></figure></div>



<h3 class="wp-block-heading" id="more-on-how-to-authorize-requests-from-swagger-ui-in-keycloak">Allow access to Swagger endpoints</h3>



<p class="wp-block-paragraph">I&#8217;m going to modify my <a href="https://github.com/little-pinecone/keycloak-spring-boot/blob/master/src/main/java/in/keepgrowing/keycloakspringboot/security/config/SecurityConfig.java" target="_blank" rel="noreferrer noopener">SecurityConfig</a> class to allow Swagger endpoints to be called without authentication:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    private static final String[] SWAGGER_WHITELIST = {
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/swagger-ui.html",
    };

    public static void configureApiSecurity(HttpSecurity http) throws Exception {
        http
                …
                .antMatchers(SWAGGER_WHITELIST).permitAll()
                .anyRequest().authenticated();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        configureApiSecurity(http);
    }
…</pre></div>



<h3 class="wp-block-heading" id="more-on-how-to-authorize-requests-from-swagger-ui-in-keycloak">Provide Keycloak server details</h3>



<p class="wp-block-paragraph"><code>Authorizatin Code</code> and <code>OpenID Connect Disvovery</code> require realm name and the url of the Keycloak server for proper configuration. Although we can provide them as hardcoded strings for testing purposes, I&#8217;m going to reuse the data that&#8217;s already available in <a href="https://github.com/little-pinecone/keycloak-spring-boot/blob/master/src/main/resources/application.properties" target="_blank" rel="noreferrer noopener">my application.properties file</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag"># application.properties
keycloak.realm=keep-growing
keycloak.auth-server-url=http://localhost:8024/auth
…</pre></div>



<p class="wp-block-paragraph">To access the properties in the code, I&#8217;m going to create the following short <code>record</code>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "keycloak")
public record KeycloakProperties(
        String authServerUrl,
        String realm) {
}</pre></div>



<p class="wp-block-paragraph">That&#8217;s all we need to inject these properties into our Swagger config if our project uses a Java version with <a href="https://docs.oracle.com/en/java/javase/17/language/records.html" target="_blank" rel="noreferrer noopener">Record</a> support. Alternatively, follow the <a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.external-config.typesafe-configuration-properties.constructor-binding" target="_blank" rel="noreferrer noopener">Type-safe Configuration Properties::Constructor Binding</a> section in the Spring docs to use a simple class (with <code>getters</code> and <code>@ConstructorBinding</code> annotation).</p>



<p class="wp-block-paragraph">Thanks to this, I only provide Keycloak details in one place and I don&#8217;t have to painstakingly search my configuration classes to update the values. Additionally, the properties will always be in accordance with the selected application profile (<code>dev</code>, <code>production</code>, etc.).</p>



<h3 class="wp-block-heading" id="more-on-how-to-authorize-requests-from-swagger-ui-in-keycloak">Swagger authorization with the OAuth 2.0 protocol</h3>



<p class="wp-block-paragraph">The example implementation is available in the <a href="https://github.com/little-pinecone/keycloak-spring-boot" target="_blank" rel="noreferrer noopener">keycloak-spring-boot repository</a>.</p>



<p class="wp-block-paragraph">First of all, I&#8217;m going to consult the Swagger docs for a quick summary of the authorization flows available:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>The&nbsp;<em>flows</em>&nbsp;(also called&nbsp;<em>grant types</em>) are scenarios an API client performs to get an access token from the authorization server. OAuth 2.0 provides several flows suitable for different types of API clients:<br>&#8211; Authorization code,<br>&#8211; Implicit,<br>&#8211; Resource owner password credentials,<br>&#8211; Client credentials.</p><cite><a href="https://swagger.io/docs/specification/authentication/oauth2/" target="_blank" rel="noreferrer noopener">https://swagger.io/docs/specification/authentication/oauth2/</a></cite></blockquote>



<p class="wp-block-paragraph">I&#8217;m going to provide the configuration for the <a href="https://oauth.net/2/grant-types/authorization-code/" target="_blank" rel="noreferrer noopener">Authorization Code Grant</a> as this is the most secure option for my Swagger API calls. The following quote contains a brief explanation of this flow:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>When the user authorizes the application, they are redirected back to the application with a temporary code in the URL. The application exchanges that code for the access token. When the application makes the request for the access token, that request can be authenticated with the client secret, which reduces the risk of an attacker intercepting the authorization code and using it themselves.<br><br>This also means the access token is never visible to the user or their browser, so it is the most secure way to pass the token back to the application, reducing the risk of the token leaking to someone else.</p><cite><a href="https://www.oauth.com/oauth2-servers/server-side-apps/authorization-code/" target="_blank" rel="noreferrer noopener">https://www.oauth.com/oauth2-servers/server-side-apps/authorization-code/</a></cite></blockquote>



<p class="wp-block-paragraph">Make sure that the <code>Standard Flow</code> is enabled in Keycloak as it allows us to use the <code>Authorization Code</code> flow:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="319" height="45" src="https://keepgrowing.in/wp-content/uploads/2022/02/standard-flow-enabled.webp" alt="standard flow enabled in Keycloak" class="wp-image-9602" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/standard-flow-enabled.webp 319w, https://keepgrowing.in/wp-content/uploads/2022/02/standard-flow-enabled-300x42.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/standard-flow-enabled-250x35.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/standard-flow-enabled-100x14.webp 100w" sizes="auto, (max-width: 319px) 100vw, 319px" /></figure></div>



<h4 class="wp-block-heading">Configuration class</h4>



<p class="wp-block-paragraph">Let&#8217;s look at the <a href="https://swagger.io/docs/specification/authentication/oauth2/" target="_blank" rel="noreferrer noopener">example configuration documented in Swagger</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">components:
  securitySchemes:
    oAuth2AuthCode:
      type: oauth2
      description: For more information, see https://api.slack.com/docs/oauth
      flows: 
        authorizationCode:
          authorizationUrl: https://slack.com/oauth/authorize
          tokenUrl: https://slack.com/api/oauth.access
          scopes:
            users:read: Read user information
            …</pre></div>



<p class="wp-block-paragraph">In other words, in order to authorize requests in Keycloak, Swagger requires a component containing a security scheme with a particular flow. Based on this, I can provide my own setup in Java. Below you can see the full configuration class:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.documentation.config;

import in.keepgrowing.keycloakspringboot.security.config.KeycloakProperties;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@OpenAPIDefinition
public class SwaggerConfig {

    private static final String OAUTH_SCHEME_NAME = "oAuth";
    private static final String PROTOCOL_URL_FORMAT = "%s/realms/%s/protocol/openid-connect";

    @Bean
    public OpenAPI customOpenApi(KeycloakProperties keycloakProperties) {
        return new OpenAPI()
                .components(new Components() //1
                        .addSecuritySchemes(OAUTH_SCHEME_NAME, createOAuthScheme(keycloakProperties)))
                .addSecurityItem(new SecurityRequirement().addList(OAUTH_SCHEME_NAME));
    }

    private SecurityScheme createOAuthScheme(KeycloakProperties properties) {
        OAuthFlows flows = createOAuthFlows(properties); //3a

        return new SecurityScheme() //2
                .type(SecurityScheme.Type.OAUTH2)
                .flows(flows);
    }

    private OAuthFlows createOAuthFlows(KeycloakProperties properties) {
        OAuthFlow flow = createAuthorizationCodeFlow(properties);

        return new OAuthFlows()
                .authorizationCode(flow);
    }

    private OAuthFlow createAuthorizationCodeFlow(KeycloakProperties properties) {
        var protocolUrl = String.format(PROTOCOL_URL_FORMAT, properties.authServerUrl(), properties.realm());

        return new OAuthFlow()//3b
                .authorizationUrl(protocolUrl + "/auth")
                .tokenUrl(protocolUrl + "/token")
                .scopes(new Scopes().addString("openid", ""));
    }
}</pre></div>



<p class="wp-block-paragraph">There are a few things to note:</p>



<ol class="wp-block-list"><li><a href="https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#componentsObject" target="_blank" rel="noreferrer noopener">Components</a> – a collection of reusable objects that define various aspects of the Open API Specification.</li><li><a href="https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#securitySchemeObject" target="_blank" rel="noreferrer noopener">SecuritySceme</a> – here we can define our scheme type with the <code>Authorization Code</code> flow.</li><li><a href="https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#oauthFlowsObject" target="_blank" rel="noreferrer noopener">OAuthflow</a> – an object for specifying the configuration details of the selected flow. We have to follow the list of the required fields for each auth type from the screenshot below:</li></ol>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1038" height="356" src="https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields.webp" alt="required fields for Authorization Code Grant in OpenAPI" class="wp-image-9512" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields.webp 1038w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-300x103.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-1024x351.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-768x263.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-700x240.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-520x178.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-360x123.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-250x86.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/oauth-fixed-fields-100x34.webp 100w" sizes="auto, (max-width: 1038px) 100vw, 1038px" /></figure></div>



<p class="wp-block-paragraph">As a result, we&#8217;ll see that the Authiorization Code Grant will be the only available auth option in Swagger UI:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="657" height="494" src="https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-auth-code-flow.webp" alt="Swagger UI secured with Authorization Code flow for Keycloak" class="wp-image-9464" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-auth-code-flow.webp 657w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-auth-code-flow-300x226.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-auth-code-flow-520x391.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-auth-code-flow-360x271.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-auth-code-flow-250x188.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-auth-code-flow-100x75.webp 100w" sizes="auto, (max-width: 657px) 100vw, 657px" /></figure></div>



<h4 class="wp-block-heading">Adding Scopes to the config</h4>



<p class="wp-block-paragraph">In the screenshot with required fields for the OAuth flow, we can read that <code>scopes</code> field is just a map between their names and descriptions:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1038" height="101" src="https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition.webp" alt="scopes definition" class="wp-image-9519" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition.webp 1038w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-300x29.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-1024x100.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-768x75.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-700x68.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-520x51.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-360x35.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-250x24.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/scopes-definition-100x10.webp 100w" sizes="auto, (max-width: 1038px) 100vw, 1038px" /></figure></div>



<p class="wp-block-paragraph">Therefore, if you want to provide a scope, e.g. <code>address</code>, you need to add it when creating the authorization flow:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
private OAuthFlow createAuthorizationCodeFlow(KeycloakProperties properties) {
    var protocolUrl = String.format(PROTOCOL_URL_FORMAT, properties.getAuthServerUrl(), properties.getRealm());

    return new OAuthFlow()
        .authorizationUrl(protocolUrl + "/auth")
        .tokenUrl(protocolUrl + "/token")
        .scopes(new Scopes().addString("address", ""));
}</pre></div>



<p class="wp-block-paragraph">As a consequence, the list of scopes will appear in the Swagger authorization window after restarting the application:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="454" height="139" src="https://keepgrowing.in/wp-content/uploads/2022/02/authorization-code-with-scopes.webp" alt="scopes in swagger authorization for Keycloak" class="wp-image-9520" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/authorization-code-with-scopes.webp 454w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-code-with-scopes-300x92.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-code-with-scopes-360x110.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-code-with-scopes-250x77.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-code-with-scopes-100x31.webp 100w" sizes="auto, (max-width: 454px) 100vw, 454px" /></figure></div>



<p class="wp-block-paragraph">Another thing to remember is that if you don&#8217;t add the <code>openid</code> scope, you&#8217;ll get the following warning in the keycloak instance&#8217;s logs:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">Request is missing scope 'openid' so it's not treated as OIDC, but just pure OAuth2 request.</pre></div>



<p class="wp-block-paragraph">As a result, the requests are still valid OAuth2 requests. However, the behaviour might be unpredictable if you rely on the OIDC standard.</p>



<h3 class="wp-block-heading" id="more-on-how-to-authorize-requests-from-swagger-ui-in-keycloak">Swagger authorization with the OpenID Connect Discovery mechanism</h3>



<p class="wp-block-paragraph">The example implementation is available in the <a href="https://github.com/little-pinecone/spring-boot-swagger-ui-keycloak" target="_blank" rel="noreferrer noopener">spring-boot-swagger-ui-keycloak repository</a>.</p>



<p class="wp-block-paragraph">If you need more security schemes available in Swagger UI, you can easily achieve it with the <a href="https://swagger.io/docs/specification/authentication/openid-connect-discovery/" target="_blank" rel="noreferrer noopener">OIDC discovery mechanism</a>. It takes advantage of the fact that the OpenID server publishes its metadata to a well-known url:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>This specification defines a mechanism for an OpenID Connect Relying Party to discover the End-User&#8217;s OpenID Provider and obtain information needed to interact with it, including its OAuth 2.0 endpoint locations.</p><cite><a href="https://openid.net/specs/openid-connect-discovery-1_0.html" target="_blank" rel="noreferrer noopener">https://openid.net/specs/openid-connect-discovery-1_0.html</a></cite></blockquote>



<p class="wp-block-paragraph">In order to find the correct endpoint for your Keycloak realm, select the <code>OpenID Endpoint Configuration</code> option in the realm settings:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="552" height="462" src="https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings.webp" alt="realm settings with configuration endpoints" class="wp-image-9158" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings.webp 552w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-300x251.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-520x435.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-360x301.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-250x209.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-100x84.webp 100w" sizes="auto, (max-width: 552px) 100vw, 552px" /></figure></div>



<p class="wp-block-paragraph">In other words, the <code>http://localhost:8024/auth/realms/keep-growing/.well-known/openid-configuration</code> url contains the data required by the discovery mechanism to identify all available authorization schemes:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1032" height="188" src="https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2.webp" alt="openid configuration in Keycloak" class="wp-image-9530" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2.webp 1032w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-300x55.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-1024x187.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-768x140.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-700x128.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-520x95.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-360x66.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-250x46.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-2-100x18.webp 100w" sizes="auto, (max-width: 1032px) 100vw, 1032px" /></figure></div>



<h4 class="wp-block-heading">Configuration class</h4>



<p class="wp-block-paragraph">Let&#8217;s look at the <a href="https://swagger.io/docs/specification/authentication/openid-connect-discovery/" target="_blank" rel="noreferrer noopener">example configuration documented in Swagger</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">components:
  securitySchemes:
    openId:   # &lt;--- Arbitrary name for the security scheme. Used to refer to it from elsewhere.
      type: openIdConnect
      openIdConnectUrl: https://example.com/.well-known/openid-configuration
…</pre></div>



<p class="wp-block-paragraph">The config for this security scheme is very short because all necessary information will be automatically acquired form the OpenID configuration endpoint:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootswaggeruikeycloak.shared.infrastructure.config.swagger.authorization;

import in.keepgrowing.springbootswaggeruikeycloak.shared.infrastructure.config.security.KeycloakProperties;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@OpenAPIDefinition
public class SwaggerOpenIdConfig {

    private static final String OPEN_ID_SCHEME_NAME = "openId";
    private static final String OPENID_CONFIG_FORMAT = "%s/realms/%s/.well-known/openid-configuration";

    @Bean
    OpenAPI customOpenApi(KeycloakProperties keycloakProperties) {
        return new OpenAPI()
                .components(new Components()
                        .addSecuritySchemes(OPEN_ID_SCHEME_NAME, createOpenIdScheme(keycloakProperties)))
                .addSecurityItem(new SecurityRequirement().addList(OPEN_ID_SCHEME_NAME));
    }

    private SecurityScheme createOpenIdScheme(KeycloakProperties properties) {
        String connectUrl = String.format(OPENID_CONFIG_FORMAT, properties.getAuthServerUrl(), properties.getRealm());

        return new SecurityScheme()
                .type(SecurityScheme.Type.OPENIDCONNECT)
                .openIdConnectUrl(connectUrl);
    }
}</pre></div>



<p class="wp-block-paragraph">As a result, I will see all the available authorizations in my Swagger UI:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="654" height="595" src="https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-open-id-discovery.webp" alt="Swagger UI secured with OpenID Connect Discovery for Keycloak" class="wp-image-9465" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-open-id-discovery.webp 654w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-open-id-discovery-300x273.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-open-id-discovery-520x473.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-open-id-discovery-360x328.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-open-id-discovery-250x227.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-open-id-discovery-100x91.webp 100w" sizes="auto, (max-width: 654px) 100vw, 654px" /></figure></div>



<h3 class="wp-block-heading">Swagger authorization with bearer token</h3>



<p class="wp-block-paragraph">The example implementation is available in the <a href="https://github.com/little-pinecone/spring-boot-swagger-ui-keycloak" target="_blank" rel="noreferrer noopener">spring-boot-swagger-ui-keycloak repository</a>.</p>



<p class="wp-block-paragraph">What if we already have access tokens from Keycloak? We can configure Swagger UI to allow us to provide only the bearer token value. Remember to provide the recommended security features for this authorization approach: </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Similarly to&nbsp;<a href="https://swagger.io/docs/specification/authentication/basic-authentication/" target="_blank" rel="noreferrer noopener">Basic authentication</a>, Bearer authentication should only be used over HTTPS (SSL).</p><cite><a href="https://swagger.io/docs/specification/authentication/bearer-authentication/" target="_blank" rel="noreferrer noopener">https://swagger.io/docs/specification/authentication/bearer-authentication/</a></cite></blockquote>



<h4 class="wp-block-heading">Configuration class</h4>



<p class="wp-block-paragraph">Let&#8217;s look at the <a href="https://swagger.io/docs/specification/authentication/bearer-authentication/" target="_blank" rel="noreferrer noopener">example configuration documented in Swagger</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">components:
  securitySchemes:
    bearerAuth:            # arbitrary name for the security scheme
      type: http
      scheme: bearer
      bearerFormat: JWT
…</pre></div>



<p class="wp-block-paragraph">We&#8217;re going to create the security scheme with the <code>http</code> type and <code>bearer</code> scheme. The <code>bearerFormat</code> field is optional and mostly used for documentation purposes. You can see my Java configuration below:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.springbootswaggeruikeycloak.shared.infrastructure.config.swagger.authorization;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@OpenAPIDefinition
public class SwaggerBearerConfig {

    private static final String SCHEME_NAME = "bearerAuth";
    private static final String SCHEME = "bearer";

    @Bean
    OpenAPI customOpenApi() {
        return new OpenAPI()
                .components(new Components()
                        .addSecuritySchemes(SCHEME_NAME, createBearerScheme()))
                .addSecurityItem(new SecurityRequirement().addList(SCHEME_NAME));
    }

    private SecurityScheme createBearerScheme() {
        return new SecurityScheme()
                .type(SecurityScheme.Type.HTTP)
                .scheme(SCHEME);
    }
}</pre></div>



<p class="wp-block-paragraph">As a result, I will see the Bearer Authorization in my Swagger UI:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="650" height="265" src="https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-bearer-scheme.webp" alt="Bearer authorization in Swagger UI" class="wp-image-9590" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-bearer-scheme.webp 650w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-bearer-scheme-300x122.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-bearer-scheme-520x212.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-bearer-scheme-360x147.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-bearer-scheme-250x102.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/swagger-ui-with-bearer-scheme-100x41.webp 100w" sizes="auto, (max-width: 650px) 100vw, 650px" /></figure></div>



<p class="wp-block-paragraph">Make sure that the token contains user roles that your API requires (<code>realm_access</code> or <code>resource_access</code> in the screenshot below):</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="825" height="445" src="https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles.webp" alt="bearer token containing user realm roles" class="wp-image-9591" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles.webp 825w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-300x162.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-768x414.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-700x378.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-520x280.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-360x194.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-250x135.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/token-with-realm-roles-100x54.webp 100w" sizes="auto, (max-width: 825px) 100vw, 825px" /></figure></div>



<h2 class="wp-block-heading" id="why-not-other-flows">Why not other flows</h2>



<p class="wp-block-paragraph">Both <code>implicit</code> and <code>password</code> flows increase security risks and are therefore deprecated:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Please note that as of 2020, the implicit flow is about to be deprecated by OAuth 2.0 Security Best Current Practice. Recommended for most use case is Authorization Code Grant flow with PKCE.</p><cite><a href="https://spec.openapis.org/oas/latest.html#security-scheme-object" target="_blank" rel="noreferrer noopener">https://spec.openapis.org/oas/latest.html#security-scheme-object</a></cite></blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Because the client application has to collect the user’s password and send it to the authorization server, it is not recommended that this grant [<em>password</em>] be used at all anymore.</p><cite><a href="https://oauth.net/2/grant-types/password/" target="_blank" rel="noreferrer noopener">https://oauth.net/2/grant-types/password/</a></cite></blockquote>



<p class="wp-block-paragraph">In addition, you can find more information in the <em>Why not other flows</em> section of the <a href="https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/" target="_blank" rel="noreferrer noopener">Kecloak in Docker #7 – How to authorize requests via Postman</a> article.</p>



<h2 class="wp-block-heading" id="more-on-how-to-authorize-requests-from-swagger-ui-in-keycloak">Troubleshooting</h2>



<p class="wp-block-paragraph">What to check when API calls don’t work as planned?</p>



<h3 class="wp-block-heading" id="403-forbidden-error">The &#8220;Available authorizations&#8221; list is empty</h3>



<p class="wp-block-paragraph">An empty list of <code>Available authorizations</code> means that Swagger was unable to retrieve configuration from the OpenID server. You can debug the request responsible for loading Swagger UI in the browser:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1838" height="935" src="https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery.webp" alt="xsrf header blocks Swagger from open id discovery in Keycloak" class="wp-image-9536" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery.webp 1838w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-300x153.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-1024x521.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-768x391.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-1536x781.webp 1536w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-700x356.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-520x265.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-360x183.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-250x127.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/xsrf-header-blocks-open-id-discovery-100x51.webp 100w" sizes="auto, (max-width: 1838px) 100vw, 1838px" /></figure></div>



<p class="wp-block-paragraph">This failure was due to the XSRF header attached to the request. If you are using Springdoc with csrf protection enabled, be sure to update the library to at least version 1.6.6. I described this problem in the <a href="https://github.com/swagger-api/swagger-ui/issues/7750" target="_blank" rel="noreferrer noopener">Is there a way to authorize users using OpenID Connect Discovery when POST endpoints require CSRF protection?</a> issue.</p>



<h3 class="wp-block-heading" id="403-forbidden-error">CORS Error</h3>



<p class="wp-block-paragraph">&#8220;<code>No Access-Control-Allow-Origin header is present on the requested resource</code>&#8221; is an example CORS error that may appear in your browser if the <code>Web Origins</code> field is misconfigured in the Keycloak client:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1671" height="322" src="https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors.webp" alt="" class="wp-image-9539" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors.webp 1671w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-300x58.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-1024x197.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-768x148.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-1536x296.webp 1536w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-700x135.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-520x100.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-360x69.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-250x48.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/failed-cors-100x19.webp 100w" sizes="auto, (max-width: 1671px) 100vw, 1671px" /></figure></div>



<p class="wp-block-paragraph">Make sure to configure the Keycloak client to accept connections from the Swagger endpoint as shown in the following screenshot:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1016" height="106" src="https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin.webp" alt="web origin in keycloak config" class="wp-image-9540" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin.webp 1016w, https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin-300x31.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin-768x80.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin-700x73.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin-520x54.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin-360x38.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin-250x26.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/keycloak-web-origin-100x10.webp 100w" sizes="auto, (max-width: 1016px) 100vw, 1016px" /></figure></div>



<p class="wp-block-paragraph">Another reason for this error is missing authorization data. You should see a lock icon next to a secured endpoint:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="774" height="63" src="https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger.webp" alt="api endpoint in Swager secured properly" class="wp-image-9980" srcset="https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger.webp 774w, https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger-300x24.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger-768x63.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger-700x57.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger-520x42.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger-360x29.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger-250x20.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/03/lock-icon-swagger-100x8.webp 100w" sizes="auto, (max-width: 774px) 100vw, 774px" /></figure></div>



<p class="wp-block-paragraph">Furthermore, the request should contain a Bearer Token that you can see in the <code>curl</code> window:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="750" height="142" src="https://keepgrowing.in/wp-content/uploads/2022/03/curl-details.webp" alt="authorization token in Swagger UI curl details window" class="wp-image-9983" srcset="https://keepgrowing.in/wp-content/uploads/2022/03/curl-details.webp 750w, https://keepgrowing.in/wp-content/uploads/2022/03/curl-details-300x57.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/03/curl-details-700x133.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/03/curl-details-520x98.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/03/curl-details-360x68.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/03/curl-details-250x47.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/03/curl-details-100x19.webp 100w" sizes="auto, (max-width: 750px) 100vw, 750px" /></figure></div>



<p class="wp-block-paragraph">If the endpoints are not secured, make sure that the proper scheme is provided as a <code>SecurityRequirement</code>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
.addSecurityItem(new SecurityRequirement().addList(SAME_NAME_AS_USED_FOR_SECURITY_SCHEME));
…</pre></div>



<h2 class="wp-block-heading" id="more-on-how-to-authorize-requests-from-swagger-ui-in-keycloak">More on how to authorize requests from Swagger UI in Keycloak</h2>



<ul class="wp-block-list"><li>Additionally, you can find sample configurations for other Swagger authorizations in the <a href="https://github.com/little-pinecone/spring-boot-swagger-ui-keycloak" target="_blank" rel="noreferrer noopener">spring-boot-swagger-ui-keycloak</a> repository.</li><li><a href="https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type#when-to-use-the-authorization-code-flow" target="_blank" rel="noreferrer noopener">What is the OAuth 2.0 Authorization Code Grant Type?</a></li><li>Moreover, read the <a href="https://www.thomasvitale.com/keycloak-authentication-flow-sso-client/" target="_blank" rel="noreferrer noopener">Keycloak Authentication Flows, SSO Protocols and Client Configuration</a> article.</li><li>Finally, check out the <a href="https://keithtmiller.com/2020/03/18/OpenApi3-Header-setup/" target="_blank" rel="noreferrer noopener">OpenApi 3 custom setup in Spring Boot using springdoc-openapi-ui</a> example.</li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@yankrukov?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Yan Krukov</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/couple-eating-pizza-7314984/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/">Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8314</post-id>	</item>
		<item>
		<title>Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests</title>
		<link>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-2-spring-security-instead-of-keycloak-in-tests/</link>
					<comments>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-2-spring-security-instead-of-keycloak-in-tests/#respond</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Thu, 24 Feb 2022 10:39:05 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[testing]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=8309</guid>

					<description><![CDATA[<p>Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can greatly simplify our codebase. However, it adds another external dependency that will complicate the integration testing. As a remedy, we can switch to native Spring Security when executing tests to verify only the business rules for access control instead of cluttering the code with Keycloak dependencies. Prerequisites A Spring Boot project with security configuration for Keycloak described in the Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak post. Dependencies that provide support for Spring Security and testing. Below are the relevant dependencies from my project: I’m working on a Spring Boot REST API that you can find in my&#160;keycloak-spring-boot repository. If you want to run the app locally, visit the&#160;project repository on GitHub&#160;and follow the directions in the README.md file. Why we need to overwrite configuration in tests For example, after we add Keycloak config to a project, Spring MVC tests will fail to load the ApplicationContext due to the following error: Currently, there is no default way to disable Keycloak protection (note that the property keycloak.enabled=false is not supported). While we could provide just enough Keycloak configuration to run the tests, it would introduce irrelevant details into the code. Therefore, we need to ensure a security config that keeps the test code clean and still allows API access rules to be verified. Configure integration tests to use Spring Security instead of Keycloak First, we&#8217;ll make the Keycloak setup dependent on a custom application property. Then we&#8217;ll configure our tests to use just Spring Security. Make the Keycloak config load dependent on a custom property We&#8217;re going to create a custom application property to control the loading of the security config. An important point to remember is that I want Keycloak to be used by default. In other words, I only want to turn it off in testing. Create the application.properties file in the test/resources directory and copy the following property: When executing tests, Spring Boot will only see the properties defined in this file. If you have any properties that should also be used in your tests, be sure to copy them to this file as well. The advantage of this approach is that it removes all irrelevant properties from the testing context and also provides a clear view of our testing setup. Next, we need to configure our app to use Keycloak either when our custom property explicitly says so or when it hasn&#8217;t been specified at all (by default). Therefore, we&#8217;re going to aply the ConditionalOnProperty annotation to all Keycloak-related configuration classes (there are two in my project): Thanks to specifying the matchIfMissing attribute, the Keycloak configuration is our default security configuration. However, it won&#8217;t be used when running tests because we explicitly disabled it in the test/resources/application.properties file. Define common security rules As you may have noticed, we don&#8217;t have any security setup for our testing at the moment. Ideally, we want to test the business rules for API security without duplicating it in the tests. Therefore, I&#8217;m going to extract the common configuration into a static method so that I can reuse it in my tests: As a result, I can reuse the SecurityConfig::configureApiSecurity method outside of the Keycloak configuration class. Apply security configuration in tests Consequently, we can now provide a separate security configuration for the tests. Create a class in the test package that: uses the @Configuration annotation, is enabled when the security.conifg.use-keycloak property is set to false, uses the SecurityConfig::configureApiSecurity method we defined earlier. You can see my conifg class below: This is all I need to apply my security config in tests without coupling it with an external authorization server. Finally, by running tests from my ProductControllerTest class, I can verify the actual configuration in logs: As we can see, a user password is generated automatically according to the default Spring Security specification and there is no mention of any Keycloak configuration. More on using Spring Security instead of Keycloak in tests Response to How to disable Keycloak question on StackOverflow Document how to use this if Keycloak is on the classpath Photo by&#160;ELEVATE&#160;from&#160;Pexels</p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-2-spring-security-instead-of-keycloak-in-tests/">Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can greatly simplify our codebase. However, it adds another external dependency that will complicate the integration testing. As a remedy, we can switch to native Spring Security when executing tests to verify only the business rules for access control instead of cluttering the code with Keycloak dependencies.</p>



<span id="more-8309"></span>



<h2 class="wp-block-heading" id="prerequisites">Prerequisites</h2>



<ul class="wp-block-list"><li>A Spring Boot project with security configuration for Keycloak described in the <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/" target="_blank" rel="noreferrer noopener">Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak</a> post.</li><li>Dependencies that provide support for Spring Security and testing. Below are the relevant dependencies from my project:</li></ul>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">&lt;!-- pom.xml --&gt;
…
&lt;dependencies&gt;
    …
    &lt;!-- Security --&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.keycloak&lt;/groupId&gt;
        &lt;artifactId&gt;keycloak-spring-boot-starter&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;!-- END of Security --&gt;

    &lt;!-- Tests --&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
        &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
        &lt;artifactId&gt;spring-security-test&lt;/artifactId&gt;
        &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;!-- END Tests --&gt;
    …
&lt;/dependencies&gt;
…</pre></div>



<ul class="wp-block-list"><li>I’m working on a Spring Boot REST API that you can find in my&nbsp;<code>keycloak-spring-boot</code> repository. If you want to run the app locally, visit the&nbsp;<a href="https://github.com/little-pinecone/keycloak-spring-boot" target="_blank" rel="noreferrer noopener">project repository on GitHub</a>&nbsp;and follow the directions in the README.md file.</li></ul>



<h2 class="wp-block-heading" id="use-keycloak-on-property">Why we need to overwrite configuration in tests</h2>



<p class="wp-block-paragraph">For example, after we add Keycloak config to a project, Spring MVC tests will fail to load the <code>ApplicationContext</code> due to the following error:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">java.io.FileNotFoundException: Unable to locate Keycloak configuration file: keycloak.json</pre></div>



<p class="wp-block-paragraph">Currently, there is no default way to disable Keycloak protection (note that the property <a href="https://issues.redhat.com/browse/KEYCLOAK-6163" target="_blank" rel="noreferrer noopener">keycloak.enabled=false is not supported</a>).</p>



<p class="wp-block-paragraph">While we could provide just enough Keycloak configuration to run the tests, it would introduce irrelevant details into the code. Therefore, we need to ensure a security config that keeps the test code clean and still allows API access rules to be verified.</p>



<h2 class="wp-block-heading" id="use-keycloak-on-property">Configure integration tests to use Spring Security instead of Keycloak</h2>



<p class="wp-block-paragraph">First, we&#8217;ll make the Keycloak setup dependent on a custom application property. Then we&#8217;ll configure our tests to use just Spring Security.</p>



<h3 class="wp-block-heading" id="use-keycloak-on-property">Make the Keycloak config load dependent on a custom property</h3>



<p class="wp-block-paragraph">We&#8217;re going to create a custom <a href="https://docs.spring.io/spring-boot/docs/2.6.3/reference/html/features.html#features.external-config" target="_blank" rel="noreferrer noopener">application property</a> to control the loading of the security config. An important point to remember is that I want Keycloak to be used by default. In other words, I only want to turn it off in testing.</p>



<p class="wp-block-paragraph">Create the <code>application.properties</code> file in the <code>test/resources</code> directory and copy the following property:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag"># src/test/resources/application.properties
security.config.use-keycloak=false</pre></div>



<p class="wp-block-paragraph">When executing tests, Spring Boot will only see the properties defined in this file. If you have any properties that should also be used in your tests, be sure to copy them to this file as well. The advantage of this approach is that it removes all irrelevant properties from the testing context and also provides a clear view of our testing setup.</p>



<p class="wp-block-paragraph">Next, we need to configure our app to use Keycloak either when our custom property explicitly says so or when it hasn&#8217;t been specified at all (by default). Therefore, we&#8217;re going to aply the <a href="https://docs.spring.io/spring-boot/docs/2.6.3/api/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.html" target="_blank" rel="noreferrer noopener">ConditionalOnProperty annotation</a> to all Keycloak-related configuration classes (there are two in my project): </p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;
…
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;

@KeycloakConfiguration
@ConditionalOnProperty(name = "security.config.use-keycloak", havingValue = "true", matchIfMissing = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
…</pre></div>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;
…
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnProperty(name = "security.config.use-keycloak", havingValue = "true", matchIfMissing = true)
public class KeycloakConfig {
…</pre></div>



<p class="wp-block-paragraph">Thanks to specifying the <code>matchIfMissing</code> attribute, the Keycloak configuration is our default security configuration. However, it won&#8217;t be used when running tests because we explicitly disabled it in the <code>test/resources/application.properties</code> file.</p>



<h3 class="wp-block-heading" id="use-keycloak-on-property">Define common security rules</h3>



<p class="wp-block-paragraph">As you may have noticed, we don&#8217;t have any security setup for our testing at the moment. Ideally, we want to test the business rules for API security without duplicating it in the tests. Therefore, I&#8217;m going to extract the common configuration into a static method so that I can reuse it in my tests:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

@KeycloakConfiguration
@ConditionalOnProperty(name = "security.config.use-keycloak", havingValue = "true", matchIfMissing = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    public static void configureApiSecurity(HttpSecurity http) throws Exception {
        http
                .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .and()
                .authorizeRequests()
                …
                .anyRequest().authenticated();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        configureApiSecurity(http);
    }
    …
}</pre></div>



<p class="wp-block-paragraph">As a result, I can reuse the <code>SecurityConfig::configureApiSecurity</code> method outside of the Keycloak configuration class.</p>



<h3 class="wp-block-heading" id="use-keycloak-on-property">Apply security configuration in tests</h3>



<p class="wp-block-paragraph">Consequently, we can now provide a separate security configuration for the tests. Create a class in the <code>test</code> package that:</p>



<ul class="wp-block-list"><li>uses the <a href="https://docs.spring.io/spring-boot/docs/2.6.3/reference/htmlsingle/#using.configuration-classes" target="_blank" rel="noreferrer noopener">@Configuration</a> annotation,</li><li>is enabled when the <code>security.conifg.use-keycloak</code> property is set to <code>false</code>,</li><li>uses the <code>SecurityConfig::configureApiSecurity</code> method we defined earlier.</li></ul>



<p class="wp-block-paragraph">You can see my conifg class below:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@ConditionalOnProperty(name = "security.config.use-keycloak", havingValue = "false")
public class TestSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        SecurityConfig.configureApiSecurity(http);
    }
}</pre></div>



<p class="wp-block-paragraph">This is all I need to apply my security config in tests without coupling it with an external authorization server.</p>



<p class="wp-block-paragraph">Finally, by running tests from my <code>ProductControllerTest</code> class, I can verify the actual configuration in logs:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1424" height="239" src="https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs.webp" alt="logs showing that Spring Security was used instead of Keycloak in tests" class="wp-image-9338" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs.webp 1424w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-300x50.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-1024x172.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-768x129.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-700x117.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-520x87.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-360x60.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-250x42.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/success-test-logs-100x17.webp 100w" sizes="auto, (max-width: 1424px) 100vw, 1424px" /></figure></div>



<p class="wp-block-paragraph">As we can see, a user password is generated automatically according to the default Spring Security specification and there is no mention of any Keycloak configuration.</p>



<h2 class="wp-block-heading" id="more-on-using-spring-security-instead-of-keycloak-in-tests">More on using Spring Security instead of Keycloak in tests</h2>



<ul class="wp-block-list"><li>Response to <a href="https://stackoverflow.com/a/55369181/7995881" target="_blank" rel="noreferrer noopener">How to disable Keycloak question</a> on StackOverflow</li><li><a href="https://github.com/ch4mpy/spring-addons/issues/2" target="_blank" rel="noreferrer noopener">Document how to use this if Keycloak is on the classpath</a></li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@elevate?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">ELEVATE</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/man-giving-a-tour-of-a-brewery-3009799/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-2-spring-security-instead-of-keycloak-in-tests/">Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-2-spring-security-instead-of-keycloak-in-tests/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8309</post-id>	</item>
		<item>
		<title>Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak</title>
		<link>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/</link>
					<comments>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/#respond</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Thu, 24 Feb 2022 10:27:24 +0000</pubDate>
				<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[user management]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=8795</guid>

					<description><![CDATA[<p>Keycloak provides simple integration with Spring applications. As a result, we can easily configure our Spring Boot API security to delegate authentication and authorization to a Keycloak server. Prerequisites Docker Engine and Docker Compose (for running an example Keycloak instance), JDK and Maven (for running an example Spring Boot project). I’m working on a Spring Boot REST API that you can find in my keycloak-spring-boot repository. If you want to run the app locally, visit the project repository on GitHub and follow the directions in the README.md file. My project contains Spring MVC tests that allow me to verify the security configuration. However, you can learn how to authorize Postman requests in Keycloak or configure Swagger UI to comply with the security setup to manually test your API. The solution that I’ll show works for the following sample client configuration: Securing Spring Boot applications with Keycloak I&#8217;m going to add maven dependencies and required properties for Keycloak integration. Then, before I actually restrict access to my API endpoints, I will define a basic security configuration and test that both tools work together properly. Add dependencies First, I&#8217;m going to add the required dependencies to my project. In addition to the Keycloak and Spring Security starters for Spring Boot, I&#8217;ll add the Keycloak bom for adapters: Add application properties I&#8217;m running my Keycloak instance in a Docker container. For my sample client configuration, see the screenshot from the Prerequisites section. I&#8217;m going to copy some information from my Keycloak client setup to the application.properties file: Below is a brief explanation of the properties: realm – my example realm name; resource – my example client name; auth-server-url – you can get the value from the Keycloak OIDC URI endpoint list by visiting the realm settings, clicking the OpenID Endpoint Configuration and copying the auth path: credentials.secret – my example client has the confidential access type. Therefore, I have to copy the secret value from the Credentials tab: If you want to access user roles at the client level and not user roles at the realm level, add the following property: However, in my example I&#8217;m using realm roles for users. Add security config I&#8217;m going to create two configuration classes to handle my Keycloak setup. The first one provides the ability to resolve my Keycloak config based on the application.properties file. I&#8217;m going to enclose it in a separate file to avoid the circular dependency issue (described in Javadoc in the snippet below): Next, I&#8217;m going to add the following class containing a Keycloak-based Spring security configuration: There are a few things to note: @KeycloakConfiguration – this metadata annotation provides all annotations that are needed to integrate Keycloak in Spring Security (e.g. for enabling Spring Security or configuring component scanning); KeycloakWebSecurityConfigurerAdapter – by extending this class we gain a useful base class for creating a WebSecurityConfigurer instance secured by Keycloak; SecurityConfig::configure – we&#8217;re going to overwrite the basic Spring Security behaviour, first by calling the parent implementation and then by adding our own csrf and endpoint protection config; SecurityConfig::configureGlobal – furthermore, we have to register the KeycloakAuthenticationProvider with the authentication manager; SecurityConfig::getKeycloakAuthenticationProvider – my auxiliary method for customising the authentication provider. Namely, I&#8217;m providing a simple one-to-one GrantedAuthoritiesMapper which adds the ROLE_ prefix and converts the authority value to upper case (e.g. a chief-operating-officer role from Keycloak realm becomes ROLE_CHIEF-OPERATING-OFFICER in my Spring Boot app); SecurityConfig::sessionAuthenticationStrategy – the session authentication strategy bean has to be of type RegisterSessionAuthenticationStrategy for public or confidential applications (NullAuthenticatedSessionStrategy for bearer-only applications). Test basic Keycloak configuration for Spring Security Although I haven&#8217;t restricted access to any endpoint in my API, I&#8217;m still going to test the current setup. I&#8217;m going to enable the DEBUG log lever for security by adding the following property to my application.properties file: As a result, I can verify the configuration details and see that Keycloak filters are present in the filter chain: Moreover, Spring Security doesn&#8217;t create a user password which would be its default behaviour without the Keycloak configuration. At this point, my Spring Boot application is delegating authentication and authorization processes to Keycloak. However, I am still free to call the endpoints as they are not explicitly secured. Secure endpoints Next, I&#8217;m going to restrict access to the API endpoints by replacing anyRequest().permitAll() with the anyRequest().authenticated() line: After restarting the application, I can see in its logs that all endpoints are protected: As a result, my Postman setup and Swagger UI config require additional configuration to allow me to make API calls. Update tests after configuring Spring Security to use Keycloak Configuring security in a project will break existing Spring MVC tests. Therefore, below you will find some details that require updating. Disable Keycloak in tests and use plain Spring Security I don&#8217;t want to clutter tests with the configuration of an external authorization service. Therefore, I&#8217;m going to configure my Spring MVC tests to use Spring Security instead of Keycloak. For full instructions on how to apply a different security configuration in tests, see the Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests post. Mock an authenticated user Fortunately, Spring Security provides the @WithMockUser annotation. We can apply it to a specific test or an entire class. In the following example test method, we can see how to use this annotation in a single test while keeping the default user data: Additionally, we can customise the username, password, roles and authorities (the latter two are exclusive) that our mocked user will receive: Include csrf protection As you may have noticed, my security configuration uses csrf protection. Therefore, I have to add the SecurityMockMvcRequestPostProcessors::csrf method that automatically populates a valid CSRF token in my POST request: Read more on integrating Spring Security with Keycloak Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI Kecloak in Docker #7 – How to authorize requests via Postman Securing Spring Boot with Keycloak documentation for Keycloak 16.1.1 [&#8230;]</p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/">Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Keycloak provides simple integration with Spring applications. As a result, we can easily configure our Spring Boot API security to delegate authentication and authorization to a Keycloak server.</p>



<span id="more-8795"></span>



<h2 class="wp-block-heading" id="prerequisites">Prerequisites</h2>



<ul class="wp-block-list"><li><a href="https://docs.docker.com/engine/" target="_blank" rel="noreferrer noopener">Docker Engine</a> and <a href="https://docs.docker.com/compose/install/" target="_blank" rel="noreferrer noopener">Docker Compose</a> (for running an example Keycloak instance), <a href="https://keepgrowing.in/java/how-to-install-openjdk-17-on-ubuntu/" target="_blank" rel="noreferrer noopener">JDK</a> and <a href="https://keepgrowing.in/java/how-to-fix-error-executing-maven-issue-after-updating-to-java-17/" target="_blank" rel="noreferrer noopener">Maven</a> (for running an example Spring Boot project).</li><li>I’m working on a Spring Boot REST API that you can find in my <code>keycloak-spring-boot</code> repository. If you want to run the app locally, visit the <a href="https://github.com/little-pinecone/keycloak-spring-boot" target="_blank" rel="noreferrer noopener">project repository on GitHub</a> and follow the directions in the README.md file.</li><li>My project contains Spring MVC tests that allow me to verify the security configuration. However, you can learn <a href="https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/" target="_blank" rel="noreferrer noopener">how to authorize Postman requests in Keycloak</a> or <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/" target="_blank" rel="noreferrer noopener">configure Swagger UI to comply with the security setup</a> to manually test your API.</li><li>The solution that I’ll show works for the following sample client configuration:</li></ul>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="669" height="955" src="https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri.webp" alt="Keycloak client to be integrated with Spring Security " class="wp-image-9253" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri.webp 669w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-210x300.webp 210w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-520x742.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-360x514.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-250x357.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-100x143.webp 100w" sizes="auto, (max-width: 669px) 100vw, 669px" /></figure></div>



<h2 class="wp-block-heading" id="prerequisites">Securing Spring Boot applications with Keycloak</h2>



<p class="wp-block-paragraph">I&#8217;m going to add maven dependencies and required properties for Keycloak integration. Then, before I actually restrict access to my API endpoints, I will define a basic security configuration and test that both tools work together properly. </p>



<h3 class="wp-block-heading" id="add-adapter">Add dependencies</h3>



<p class="wp-block-paragraph">First, I&#8217;m going to add the <a href="https://www.keycloak.org/docs/16.1/securing_apps/#_spring_boot_adapter" target="_blank" rel="noreferrer noopener">required dependencies</a> to my project. In addition to the Keycloak and Spring Security starters for Spring Boot, I&#8217;ll add the <a href="https://mvnrepository.com/artifact/org.keycloak.bom/keycloak-adapter-bom" target="_blank" rel="noreferrer noopener">Keycloak bom for adapters</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">&lt;!-- pom.xml --&gt;
…
&lt;properties&gt;
    …
    &lt;keycloak-adapter.version&gt;16.1.1&lt;/keycloak-adapter.version&gt;
&lt;/properties&gt;
&lt;dependencyManagement&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.keycloak.bom&lt;/groupId&gt;
            &lt;artifactId&gt;keycloak-adapter-bom&lt;/artifactId&gt;
            &lt;version&gt;${keycloak-adapter.version}&lt;/version&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;
&lt;dependencies&gt;
…
&lt;dependency&gt;
    &lt;groupId&gt;org.keycloak&lt;/groupId&gt;
    &lt;artifactId&gt;keycloak-spring-boot-starter&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
&lt;/dependency&gt;
…
&lt;/dependencies&gt;
…</pre></div>



<h3 class="wp-block-heading" id="add-application-properties">Add application properties</h3>



<p class="wp-block-paragraph">I&#8217;m <a href="https://keepgrowing.in/tools/keycloak-in-docker-1-how-to-run-keycloak-in-a-docker-container/" target="_blank" rel="noreferrer noopener">running my Keycloak instance in a Docker container</a>. For my sample client configuration, see the screenshot from the <em>Prerequisites</em> section.</p>



<p class="wp-block-paragraph">I&#8217;m going to copy some information from my Keycloak client setup to the <code>application.properties</code> file:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag"># src/main/resources/application.properties
keycloak.realm=keep-growing
keycloak.resource=spring-boot-example-app
keycloak.auth-server-url=http://localhost:8024/auth
keycloak.credentials.secret=QjLCjk1I9sugcZSDFCsyAkoLOqAHDLKC</pre></div>



<p class="wp-block-paragraph">Below is a brief explanation of the properties:</p>



<ul class="wp-block-list"><li><code>realm</code> – my example realm name;</li><li><code>resource</code> – my example client name;</li><li><code>auth-server-url</code> – you can get the value from the <a href="https://www.keycloak.org/docs/16.1/server_admin/#con-server-oidc-uri-endpoints_server_administration_guide" target="_blank" rel="noreferrer noopener">Keycloak OIDC URI endpoint list</a> by visiting the realm settings, clicking the <code>OpenID Endpoint Configuration</code> and copying the <code>auth</code> path:</li></ul>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1032" height="188" src="https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1.webp" alt="" class="wp-image-9376" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1.webp 1032w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-300x55.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-1024x187.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-768x140.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-700x128.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-520x95.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-360x66.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-250x46.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1-100x18.webp 100w" sizes="auto, (max-width: 1032px) 100vw, 1032px" /></figure></div>



<ul class="wp-block-list"><li><code>credentials.secret</code> – my example client has the <code>confidential</code> access type. Therefore, I have to copy the <code>secret</code> value from the <code>Credentials</code> tab:</li></ul>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1307" height="429" src="https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret.webp" alt="client secret in Keycloak" class="wp-image-9163" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret.webp 1307w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-300x98.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-1024x336.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-768x252.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-700x230.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-520x171.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-360x118.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-250x82.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-100x33.webp 100w" sizes="auto, (max-width: 1307px) 100vw, 1307px" /></figure></div>



<p class="wp-block-paragraph">If you want to access user roles at the client level and not user roles at the realm level, add the following property:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag"># src/main/resources/application.properties
…
keycloak.use-resource-role-mappings=true</pre></div>



<p class="wp-block-paragraph">However, in my example I&#8217;m using realm roles for users.</p>



<h3 class="wp-block-heading" id="add-adapter">Add security config</h3>



<p class="wp-block-paragraph">I&#8217;m going to create two configuration classes to handle my Keycloak setup.</p>



<p class="wp-block-paragraph">The first one provides the ability to resolve my Keycloak config based on the <code>application.properties</code> file. I&#8217;m going to enclose it in a separate file to avoid the circular dependency issue (described in Javadoc in the snippet below):</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * The {@code KeycloakConfigResolver} bean is not defined in a configuration class that extends
 * {@code KeycloakWebSecurityConfigurerAdapter} to avoid the {@code Circular References} problem in Spring Boot from version 2.6.0.
 *
 * @see &lt;a href="https://github.com/keycloak/keycloak/issues/8857"&gt;Application don't start because of Circular Reference due to dependency injection&lt;/a&gt;
 */
@Configuration
public class KeycloakConfig {

    @Bean
    public KeycloakConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }
}</pre></div>



<p class="wp-block-paragraph">Next, I&#8217;m going to add the following class containing a <a href="https://www.keycloak.org/docs/16.1/securing_apps/#java-configuration" target="_blank" rel="noreferrer noopener">Keycloak-based Spring security configuration</a>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">package in.keepgrowing.keycloakspringboot.security.config;

import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

@KeycloakConfiguration //1
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { //2

    @Override
    protected void configure(HttpSecurity http) throws Exception { //3
        super.configure(http);
        http
                .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .and()
                .authorizeRequests()
                .anyRequest().permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) { //4
        auth.authenticationProvider(getKeycloakAuthenticationProvider());
    }

    private KeycloakAuthenticationProvider getKeycloakAuthenticationProvider() { //5
        KeycloakAuthenticationProvider authenticationProvider = keycloakAuthenticationProvider();
        var mapper = new SimpleAuthorityMapper();
        mapper.setConvertToUpperCase(true);
        authenticationProvider.setGrantedAuthoritiesMapper(mapper);

        return authenticationProvider;
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { //6
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }
}</pre></div>



<p class="wp-block-paragraph">There are a few things to note:</p>



<ol class="wp-block-list"><li><code>@KeycloakConfiguration</code> – this metadata annotation provides all annotations that are needed to integrate Keycloak in Spring Security (e.g. for enabling Spring Security or configuring component scanning);</li><li><code>KeycloakWebSecurityConfigurerAdapter</code> – by extending <a href="https://www.javadoc.io/doc/org.keycloak/keycloak-spring-security-adapter/16.1.1/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.html" target="_blank" rel="noreferrer noopener">this class</a> we gain a useful base class for creating a <a href="https://docs.spring.io/spring-security/site/docs/5.6.1/api/org/springframework/security/config/annotation/web/WebSecurityConfigurer.html" target="_blank" rel="noreferrer noopener">WebSecurityConfigurer</a> instance secured by Keycloak;</li><li><code>SecurityConfig::configure</code> – we&#8217;re going to overwrite the basic Spring Security behaviour, first by calling the parent implementation and then by adding our own csrf and endpoint protection config; </li><li><code>SecurityConfig::configureGlobal</code> – furthermore, we have to register the <a href="https://javadoc.io/static/org.keycloak/keycloak-spring-security-adapter/16.1.1/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.html" target="_blank" rel="noreferrer noopener">KeycloakAuthenticationProvider</a> with the authentication manager;</li><li><code>SecurityConfig::getKeycloakAuthenticationProvider</code> – my auxiliary method for customising the authentication provider. Namely, I&#8217;m providing <a href="https://docs.spring.io/spring-security/site/docs/5.6.1/api/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.html" target="_blank" rel="noreferrer noopener">a simple one-to-one GrantedAuthoritiesMapper</a> which adds the <code>ROLE_</code> prefix and converts the authority value to upper case (e.g. a <code>chief-operating-officer</code> role from Keycloak realm becomes <code>ROLE_CHIEF-OPERATING-OFFICER</code> in my Spring Boot app);</li><li><code>SecurityConfig::sessionAuthenticationStrategy</code> – the <a href="https://www.keycloak.org/docs/16.1/securing_apps/#java-configuration" target="_blank" rel="noreferrer noopener">session authentication strategy</a> bean has to be of type <code>RegisterSessionAuthenticationStrategy</code> for <code>public</code> or <code>confidential</code> applications (<code>NullAuthenticatedSessionStrategy</code> for <code>bearer-only</code> applications).</li></ol>



<h3 class="wp-block-heading" id="test-basic-keycloak-configuration-for-spring-security">Test basic Keycloak configuration for Spring Security</h3>



<p class="wp-block-paragraph">Although I haven&#8217;t restricted access to any endpoint in my API, I&#8217;m still going to test the current setup. I&#8217;m going to enable the DEBUG log lever for security by adding the following property to my <code>application.properties</code> file:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">logging.level.org.springframework.security=DEBUG</pre></div>



<p class="wp-block-paragraph">As a result, I can verify the configuration details and see that Keycloak filters are present in the filter chain:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
DEBUG 12469 --- [main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [permitAll] for any request
INFO 12469 --- [main] o.s.s.web.DefaultSecurityFilterChain      : Will secure any request with […, org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter@439e3cb4, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter@31e76a8d, …]
…</pre></div>



<p class="wp-block-paragraph">Moreover, Spring Security doesn&#8217;t create a user password which would be its default behaviour without the Keycloak configuration.</p>



<p class="wp-block-paragraph">At this point, my Spring Boot application is delegating authentication and authorization processes to Keycloak. However, I am still free to call the endpoints as they are not explicitly secured.</p>



<h2 class="wp-block-heading" id="add-adapter">Secure endpoints</h2>



<p class="wp-block-paragraph">Next, I&#8217;m going to restrict access to the API endpoints by replacing <code>anyRequest().permitAll()</code> with the <code>anyRequest().authenticated()</code> line:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
                …
                .authorizeRequests()
                .anyRequest().authenticated();
    }</pre></div>



<p class="wp-block-paragraph">After restarting the application, I can see in its logs that all endpoints are protected:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
DEBUG 13361 --- [main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [authenticated] for any request
…</pre></div>



<p class="wp-block-paragraph">As a result, my <a href="https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/" target="_blank" rel="noreferrer noopener">Postman setup</a> and <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/" target="_blank" rel="noreferrer noopener">Swagger UI config</a> require additional configuration to allow me to make API calls.</p>



<h2 class="wp-block-heading" id="add-adapter">Update tests after configuring Spring Security to use Keycloak</h2>



<p class="wp-block-paragraph">Configuring security in a project will break existing Spring MVC tests. Therefore, below you will find some details that require updating.</p>



<h3 class="wp-block-heading" id="disable-keycloak-in-tests-and-use-plain-spring-security">Disable Keycloak in tests and use plain Spring Security</h3>



<p class="wp-block-paragraph">I don&#8217;t want to clutter tests with the configuration of an external authorization service. Therefore, I&#8217;m going to configure my Spring MVC tests to use Spring Security instead of Keycloak. For full instructions on how to apply a different security configuration in tests, see the <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-2-spring-security-instead-of-keycloak-in-tests/" target="_blank" rel="noreferrer noopener">Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests</a> post.</p>



<h3 class="wp-block-heading" id="add-adapter">Mock an authenticated user</h3>



<p class="wp-block-paragraph">Fortunately, <a href="https://docs.spring.io/spring-security/reference/servlet/test/method.html#test-method-withmockuser" target="_blank" rel="noreferrer noopener">Spring Security provides the @WithMockUser annotation</a>. We can apply it to a specific test or an entire class. In the following example test method, we can see how to use this annotation in a single test while keeping the default user data:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">@Test
@WithMockUser
void shouldReturnAllProducts() throws Exception {
    ProductResponse productResponse = productResponseProvider.full();
    String expected = objectMapper.writeValueAsString(List.of(productResponse));

    when(apiFacade.findAll())
        .thenReturn(List.of(productResponse));

    mvc.perform(get("/api/products")
                    .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().json(expected));
    }</pre></div>



<p class="wp-block-paragraph">Additionally, we can customise the <code>username</code>, <code>password</code>, <code>roles</code> and <code>authorities</code> (the latter two are exclusive) that our mocked user will receive:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">@WithMockUser(username = "thomas", password = "test", roles = {"EDITOR"})</pre></div>



<h3 class="wp-block-heading" id="add-adapter">Include csrf protection</h3>



<p class="wp-block-paragraph">As you may have noticed, my security configuration uses csrf protection. Therefore, I have to add the <code>SecurityMockMvcRequestPostProcessors::csrf</code> method that automatically populates a valid CSRF token in my POST request:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">@Test
@WithMockUser
void shouldSaveNewProduct() throws Exception {
    ProductRequest newProduct = productRequestProvider.full();
    ProductResponse savedProduct = productResponseProvider.full();
    String expected = objectMapper.writeValueAsString(savedProduct);

    when(apiFacade.save(newProduct))
            .thenReturn(savedProduct);

    mvc.perform(post("/api/products")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(newProduct))
                    .with(csrf()))
            .andExpect(status().isOk())
            .andExpect(content().json(expected));
}</pre></div>



<h2 class="wp-block-heading" id="read-more-on-integrating-spring-security-with-keycloak">Read more on integrating Spring Security with Keycloak</h2>



<ul class="wp-block-list"><li><a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-2-spring-security-instead-of-keycloak-in-tests/" target="_blank" rel="noreferrer noopener">Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests</a></li><li><a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-3-how-to-authorize-requests-in-swagger-ui/" target="_blank" rel="noreferrer noopener">Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI</a></li><li><a href="https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/" target="_blank" rel="noreferrer noopener">Kecloak in Docker #7 – How to authorize requests via Postman</a></li><li>Securing Spring Boot with Keycloak documentation for <a href="https://www.keycloak.org/docs/16.1/securing_apps/#_spring_boot_adapter" target="_blank" rel="noreferrer noopener">Keycloak 16.1.1</a> and <a href="https://www.keycloak.org/docs/17.0/securing_apps/#_spring_boot_adapter" target="_blank" rel="noreferrer noopener">Keycloak 17.0.0</a>.</li><li><a href="https://keepgrowing.in/tools/keycloak-in-docker-1-how-to-run-keycloak-in-a-docker-container/" target="_blank" rel="noreferrer noopener">Keycloak in Docker #1 – How to run Keycloak in a Docker container</a> article.</li><li><a href="https://www.thomasvitale.com/spring-security-keycloak/" target="_blank" rel="noreferrer noopener">Spring Security and Keycloak to Secure a Spring Boot Application &#8211; A First Look</a></li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@cottonbro?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">cottonbro</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/a-high-school-student-in-white-top-looking-at-camera-6208713/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/">Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/java/springboot/keycloak-with-spring-boot-1-configure-spring-security-with-keycloak/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8795</post-id>	</item>
		<item>
		<title>Kecloak in Docker #7 – How to authorize requests via Postman</title>
		<link>https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/</link>
					<comments>https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/#respond</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Tue, 08 Feb 2022 11:18:54 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[Postman]]></category>
		<category><![CDATA[user management]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=9109</guid>

					<description><![CDATA[<p>Postman comes with a wide variety of OAuth 2.0 compliant configuration options that allow us to authorize requests against a Keycloak protected API. The current standard recommendation is to use Authorization Code Flow with PKCE extension. Prerequisites Minimum Postman version 7.23. The sample collection I’m using for this article is in my public Postman workspace and is part of my&#160;keycloak-spring-boot&#160;application. If you want to run the project locally (it requires Docker for running a Keycloak instance), visit the&#160;project repository on GitHub&#160;and follow the directions in the README.md file. If this is your first attempt to run Keycloak in Docker, I recommend reading the post&#160;Keycloak in Docker # 1 – How to run Keycloak in a Docker container, as I explained the basic configuration there. The solution that I&#8217;ll show works for the following sample client configuration: Why we should use the PKCE Grant Type to authorize Postman requests in Keycloak I&#8217;ll show you how to get access tokens with the Proof Key for Code Exchange Grant Type (abbreviated PKCE, pronounced “pixie”) which is an extension to the Authorization Code Grant Type. The reason for using this particular flow in place of regular Authorization Code is because it provides additional protection against CSRF and authorization code injection attacks. As we can read in the Authorization Code Grant Type documentation: It is recommended that all clients use the&#160;PKCE&#160;extension with this flow as well to provide better security. https://oauhttps://oauth.net/2/grant-types/authorization-code/ Furthermore, the PKCE description states that: PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent CSRF and authorization code injection attacks. https://oauth.net/2/pkce/ In addition, my example Keycloak client is configured with the confidential Access Type. Consequently, it provides client secrets when exchanging temporary codes for tokens. This configuration may appear to provide sufficient protection. However, the documentation advocates using the PKCE extension even when we already apply client secrets: PKCE is&#160;not&#160;a replacement for a client secret, and PKCE is recommended even if a client is using a client secret. https://oauth.net/2/pkce/ Provide the data required for authorization in Keycloak to the Postman environment In order to execute the authorization flow from Postman, I will have to enter some confidential and environment-sensitive details, e.g. Client Secret, Auth URL etc.: I will store the sensitive data as environment variables. First, click the Environment quick look button (the eye icon) and click Edit for the selected environment. Then, you can start adding variables. Below you&#8217;ll see what information we need for the authorization flow and where to find the values. Callback URL Postman uses this url to extract the access token after a successful authorization in Keycloak. This is the Redirect URI value that I specified for my client in Keycloak: I&#8217;m going to create the {{redirectUri}} variable with the http://localhost://8080/* value. Auth URL and Access Token URL I&#8217;m going to provide the authorization and token urls from the Keycloak OIDC URI endpoint list. To get the values, visit the general realm settings and click the OpenID Endpoint Configuration: We&#8217;re going to see the authorization and token endpoints in the list below: Make sure that the host is consistent with the security properties in your API. If you use 127.0.0.1 instead of localhost in the API security config, consequently use the 127.0.0.1 value for the urls in Postman. I&#8217;m going to create the following variables in Postman: {{authUrl}} with the http://localhost:8024/auth/realms/keep-growing/protocol/openid-connect/auth value {{accessTokenUrl}} with the http://localhost:8024/auth/realms/keep-growing/protocol/openid-connect/token value. Client ID It&#8217;s the identifier for our client: I&#8217;m going to copy that value and put it in the {{clientId}} variable. Client secret As I mentioned before, my sample client has the confidential access type. Therefore, its configuration includes the Credentials tab, where I generated the following secret: I&#8217;m going to copy that value and put it in the {{clientSecret}} variable. Full variable list To summarize, all the environment variables I have added to my Postman collection are below: If your API uses csrf protection, read the How to add X-XSRF-TOKEN header to Postman requests article. Otherwise, you&#8217;ll get 403 errors even after completing this tutorial. Configuration required to authorize Postman requests in Keycloak Now I will set up authorization for my Postman collection using the variables mentioned above and providing some additional information. First, I&#8217;ll edit the collection: Then, I&#8217;ll and go the Authorization tab and select the OAuth 2.0 authorization type to configure a new token. Below you&#8217;ll see what additional information I&#8217;m going to provide. Add authorization data to I&#8217;m going to select the Request Headers option. Token Name This is an arbitrary value to distinguish this particular token from others you keep in Postman. I&#8217;m going to call it spring-boot-example-app token. Grant Type I&#8217;m going to select the Authorization Code (With PKCE) option. Scope Verify what scopes are available for your client.: I&#8217;m going to provide the profile email value here. Client Authentication I&#8217;m going to select the Send client credentials in body option. Full configuration You can see the complete configuration in the screenshot below: Get a new Access Token Finally, we can click the Get new Access Token button. We&#8217;re going to see the following Postman screen informing us that authentication will be done through a browser: Meanwhile, our authorization server will provide the a login form. Below you can see my Keycloak login screen where I authenticate as an example user of my realm: After successful authentication, we will see the following screen for a few seconds: As a result, a new spring-boot-example token value is available in the Manage Access Token window. Click the Use Token button: You&#8217;ll see the token value in the Current Token section: Furthermore, we can verify the token payload by decoding it with jwt.io: Make the token available in all requests To make this token accessible in all requests in my collection, I&#8217;m going to select the Inherit auth from parent option in the request Authorization tab: As a result, Keycloak will authorize all requests with this config from my Postman collection. Update and manage Access Tokens When the token expires, generate a new [&#8230;]</p>
<p>The post <a href="https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/">Kecloak in Docker #7 – How to authorize requests via Postman</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Postman comes with a wide variety of OAuth 2.0 compliant configuration options that allow us to authorize requests against a Keycloak protected API. The current standard recommendation is to use Authorization Code Flow with PKCE extension.</p>



<span id="more-9109"></span>



<h2 class="wp-block-heading" id="prerequisites">Prerequisites</h2>



<ul class="wp-block-list"><li>Minimum <a href="https://blog.postman.com/whats-new-in-postman-7-23/" target="_blank" rel="noreferrer noopener">Postman version 7.23</a>.</li><li>The sample collection I’m using for this article is in my public Postman workspace and is part of my&nbsp;<code>keycloak-spring-boot</code>&nbsp;application. If you want to run the project locally (it requires Docker for running a Keycloak instance), visit the&nbsp;<a href="https://github.com/little-pinecone/keycloak-spring-boot" target="_blank" rel="noreferrer noopener">project repository on GitHub</a>&nbsp;and follow the directions in the README.md file.</li><li>If this is your first attempt to run Keycloak in Docker, I recommend reading the post&nbsp;<a href="https://keepgrowing.in/tools/keycloak-in-docker-1-how-to-run-keycloak-in-a-docker-container/" target="_blank" rel="noreferrer noopener">Keycloak in Docker # 1 – How to run Keycloak in a Docker container</a>, as I explained the basic configuration there.</li><li>The solution that I&#8217;ll show works for the following sample client configuration:</li></ul>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="669" height="955" src="https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri.webp" alt="client configuration in Keycloak" class="wp-image-9253" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri.webp 669w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-210x300.webp 210w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-520x742.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-360x514.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-250x357.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/client-config-with-new-redirect-uri-100x143.webp 100w" sizes="auto, (max-width: 669px) 100vw, 669px" /></figure></div>



<h2 class="wp-block-heading" id="prerequisites">Why we should use the PKCE Grant Type to authorize Postman requests in Keycloak</h2>



<p class="wp-block-paragraph">I&#8217;ll show you how to get access tokens with the <code>Proof Key for Code Exchange</code> <a href="https://oauth.net/2/grant-types/" target="_blank" rel="noreferrer noopener">Grant Type</a> (<a href="https://www.oauth.com/oauth2-servers/pkce/" target="_blank" rel="noreferrer noopener">abbreviated PKCE, pronounced “pixie”</a>) which is an extension to the <code>Authorization Code</code> Grant Type. The reason for using this particular flow in place of regular <code>Authorization Code</code> is because it provides additional protection against CSRF and authorization code injection attacks.</p>



<p class="wp-block-paragraph">As we can read in the <code>Authorization Code</code> Grant Type documentation:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>It is recommended that all clients use the&nbsp;<a href="https://oauth.net/2/pkce/" target="_blank" rel="noreferrer noopener">PKCE</a>&nbsp;extension with this flow as well to provide better security.</p><cite><a href="https://oauth.net/2/pkce/" target="_blank" rel="noreferrer noopener">https://oauhttps://oauth.net/2/grant-types/authorization-code/</a></cite></blockquote>



<p class="wp-block-paragraph">Furthermore, the PKCE description states that:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent CSRF and authorization code injection attacks.</p><cite><a href="https://oauth.net/2/pkce/" target="_blank" rel="noreferrer noopener">https://oauth.net/2/pkce/</a></cite></blockquote>



<p class="wp-block-paragraph">In addition, my example Keycloak client is configured with the <code>confidential</code> Access Type. Consequently, it <a href="https://www.keycloak.org/docs/latest/server_admin/#_oidc-auth-flows-authorization" target="_blank" rel="noreferrer noopener">provides client secrets</a> when exchanging temporary codes for tokens. This configuration may appear to provide sufficient protection. However, the documentation advocates using the PKCE extension even when we already apply client secrets:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>PKCE is&nbsp;<em>not</em>&nbsp;a replacement for a client secret, and PKCE is recommended even if a client is using a client secret.</p><cite><a href="https://oauth.net/2/pkce/" target="_blank" rel="noreferrer noopener">https://oauth.net/2/pkce/</a></cite></blockquote>



<h2 class="wp-block-heading" id="provide-the-data-required-for-authorization-in-keycloak-to-the-postman-environment">Provide the data required for authorization in Keycloak to the Postman environment</h2>



<p class="wp-block-paragraph">In order to execute the authorization flow from Postman, I will have to enter some confidential and environment-sensitive details, e.g. <code>Client Secret</code>, <code>Auth URL</code> etc.:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="707" height="342" src="https://keepgrowing.in/wp-content/uploads/2022/02/empty-config.webp" alt="Empty Postman configuration for authorizing requests in Keycloak" class="wp-image-9209" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/empty-config.webp 707w, https://keepgrowing.in/wp-content/uploads/2022/02/empty-config-300x145.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/empty-config-700x339.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/empty-config-520x252.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/empty-config-360x174.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/empty-config-250x121.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/empty-config-100x48.webp 100w" sizes="auto, (max-width: 707px) 100vw, 707px" /></figure></div>



<p class="wp-block-paragraph">I will store the sensitive data as <a href="https://learning.postman.com/docs/sending-requests/managing-environments/#accessing-environments" target="_blank" rel="noreferrer noopener">environment variables</a>. First, click the <code>Environment quick look</code> button (the eye icon) and click <code>Edit</code> for the selected environment. Then, you can start adding variables. Below you&#8217;ll see what information we need for the authorization flow and where to find the values.</p>



<h3 class="wp-block-heading" id="token-name">Callback URL</h3>



<p class="wp-block-paragraph">Postman uses this url to extract the access token after a successful authorization in Keycloak. This is the <code>Redirect URI</code> value that I specified for my client in Keycloak:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="360" height="71" src="https://keepgrowing.in/wp-content/uploads/2022/02/redirect-uri-with-http.webp" alt="redirect uri for Keycloak client" class="wp-image-9250" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/redirect-uri-with-http.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/redirect-uri-with-http-300x59.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/redirect-uri-with-http-250x49.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/redirect-uri-with-http-100x20.webp 100w" sizes="auto, (max-width: 360px) 100vw, 360px" /></figure></div>



<p class="wp-block-paragraph">I&#8217;m going to create the <code>{{redirectUri}}</code> variable with the <code>http://localhost://8080/*</code> value.</p>



<h3 class="wp-block-heading" id="token-name">Auth URL and Access Token URL</h3>



<p class="wp-block-paragraph">I&#8217;m going to provide the <code>authorization</code> and <code>token</code> urls from the <a href="https://www.keycloak.org/docs/16.1/server_admin/#con-server-oidc-uri-endpoints_server_administration_guide" target="_blank" rel="noreferrer noopener">Keycloak OIDC URI endpoint list</a>. To get the values, visit the general realm settings and click the <code>OpenID Endpoint Configuration</code>:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="552" height="462" src="https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings.webp" alt="where to find configuration endpoints in Keycloak" class="wp-image-9158" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings.webp 552w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-300x251.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-520x435.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-360x301.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-250x209.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-settings-100x84.webp 100w" sizes="auto, (max-width: 552px) 100vw, 552px" /></figure></div>



<p class="wp-block-paragraph">We&#8217;re going to see the <code>authorization</code> and <code>token</code> endpoints in the list below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1032" height="188" src="https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints.webp" alt="OpenID Endpoint configuration in Keycloak" class="wp-image-9159" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints.webp 1032w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-300x55.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-1024x187.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-768x140.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-700x128.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-520x95.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-360x66.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-250x46.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/openid-config-endpoints-100x18.webp 100w" sizes="auto, (max-width: 1032px) 100vw, 1032px" /></figure></div>



<p class="wp-block-paragraph">Make sure that the <code>host</code> is consistent with the security <a href="https://github.com/little-pinecone/keycloak-spring-boot/blob/master/src/main/resources/application.properties" target="_blank" rel="noreferrer noopener">properties in your API</a>. If you use <code>127.0.0.1</code> instead of <code>localhost</code> in the API security config, consequently use the <code>127.0.0.1</code> value for the urls in Postman. I&#8217;m going to create the following variables in Postman:</p>



<ul class="wp-block-list"><li><code>{{authUrl}}</code> with the <code>http://localhost:8024/auth/realms/keep-growing/protocol/openid-connect/auth</code> value</li><li><code>{{accessTokenUrl}}</code> with the <code>http://localhost:8024/auth/realms/keep-growing/protocol/openid-connect/token</code> value.</li></ul>



<h3 class="wp-block-heading" id="client-id">Client ID</h3>



<p class="wp-block-paragraph">It&#8217;s the identifier for our client:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="547" height="57" src="https://keepgrowing.in/wp-content/uploads/2022/02/client-id.webp" alt="client id in Keycloak" class="wp-image-9162" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/client-id.webp 547w, https://keepgrowing.in/wp-content/uploads/2022/02/client-id-300x31.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/client-id-520x54.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/client-id-360x38.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/client-id-250x26.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/client-id-100x10.webp 100w" sizes="auto, (max-width: 547px) 100vw, 547px" /></figure></div>



<p class="wp-block-paragraph">I&#8217;m going to copy that value and put it in the <code>{{clientId}}</code> variable.</p>



<h3 class="wp-block-heading" id="client-id">Client secret</h3>



<p class="wp-block-paragraph">As I mentioned before, my sample client has the <code>confidential</code> access type. Therefore, its configuration includes the <code>Credentials</code> tab, where I generated the following secret:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1307" height="429" src="https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret.webp" alt="client secret in Keycloak" class="wp-image-9163" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret.webp 1307w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-300x98.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-1024x336.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-768x252.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-700x230.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-520x171.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-360x118.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-250x82.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/genereate-client-secret-100x33.webp 100w" sizes="auto, (max-width: 1307px) 100vw, 1307px" /></figure></div>



<p class="wp-block-paragraph">I&#8217;m going to copy that value and put it in the <code>{{clientSecret}}</code> variable.</p>



<h3 class="wp-block-heading" id="client-id">Full variable list</h3>



<p class="wp-block-paragraph">To summarize, all the environment variables I have added to my Postman collection are below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="717" height="691" src="https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri.webp" alt="Postman variables to authorize environment in Keycloak" class="wp-image-9255" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri.webp 717w, https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri-300x289.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri-700x675.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri-520x501.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri-360x347.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri-250x241.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/postman-variables-with-new-redirect-uri-100x96.webp 100w" sizes="auto, (max-width: 717px) 100vw, 717px" /></figure></div>



<p class="wp-block-paragraph">If your API uses csrf protection, read the <a href="https://keepgrowing.in/tools/how-to-add-x-xsrf-token-header-to-postman-requests/" target="_blank" rel="noreferrer noopener">How to add X-XSRF-TOKEN header to Postman requests</a> article. Otherwise, you&#8217;ll get 403 errors even after completing this tutorial. </p>



<h2 class="wp-block-heading" id="prerequisites">Configuration required to authorize Postman requests in Keycloak</h2>



<p class="wp-block-paragraph">Now I will set up authorization for my Postman collection using the variables mentioned above and providing some additional information. First, I&#8217;ll edit the collection:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="979" height="375" src="https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection.webp" alt="edit Postman collecion" class="wp-image-9055" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection.webp 979w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-300x115.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-768x294.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-700x268.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-520x199.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-360x138.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-250x96.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-100x38.webp 100w" sizes="auto, (max-width: 979px) 100vw, 979px" /></figure></div>



<p class="wp-block-paragraph">Then, I&#8217;ll and go the <code>Authorization</code> tab and select the <code>OAuth 2.0</code> authorization type to configure a new token. Below you&#8217;ll see what additional information I&#8217;m going to provide.</p>



<h3 class="wp-block-heading" id="token-name">Add authorization data to</h3>



<p class="wp-block-paragraph">I&#8217;m going to select the <code>Request Headers</code> option.</p>



<h3 class="wp-block-heading" id="token-name">Token Name</h3>



<p class="wp-block-paragraph">This is an arbitrary value to distinguish this particular token from others you keep in Postman. I&#8217;m going to call it <code>spring-boot-example-app token</code>.</p>



<h3 class="wp-block-heading" id="token-name">Grant Type</h3>



<p class="wp-block-paragraph">I&#8217;m going to select the <code>Authorization Code (With PKCE)</code> option.</p>



<h3 class="wp-block-heading" id="token-name">Scope</h3>



<p class="wp-block-paragraph">Verify what scopes are available for your client.:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1115" height="449" src="https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes.webp" alt="client scopes in Keycloak" class="wp-image-9166" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes.webp 1115w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-300x121.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-1024x412.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-768x309.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-700x282.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-520x209.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-360x145.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-250x101.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/client-scopes-100x40.webp 100w" sizes="auto, (max-width: 1115px) 100vw, 1115px" /></figure></div>



<p class="wp-block-paragraph">I&#8217;m going to provide the <code>profile email</code> value here.</p>



<h3 class="wp-block-heading" id="token-name">Client Authentication</h3>



<p class="wp-block-paragraph">I&#8217;m going to select the <code>Send client credentials in body</code> option.</p>



<h3 class="wp-block-heading" id="token-name">Full configuration</h3>



<p class="wp-block-paragraph">You can see the complete configuration in the screenshot below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="806" height="895" src="https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1.webp" alt="Postman configuration to authorize collection in Keycloak" class="wp-image-9168" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1.webp 806w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1-270x300.webp 270w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1-768x853.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1-700x777.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1-520x577.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1-360x400.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1-250x278.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-collection-level-1-100x111.webp 100w" sizes="auto, (max-width: 806px) 100vw, 806px" /></figure></div>



<h2 class="wp-block-heading" id="get-a-new-access-token">Get a new Access Token</h2>



<p class="wp-block-paragraph">Finally, we can click the <code>Get new Access Token</code> button. We&#8217;re going to see the following Postman screen informing us that authentication will be done through a browser:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="604" height="334" src="https://keepgrowing.in/wp-content/uploads/2022/02/authenticate-via-browser.webp" alt="authenticating Postman in Keycloak via browser message" class="wp-image-9142" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/authenticate-via-browser.webp 604w, https://keepgrowing.in/wp-content/uploads/2022/02/authenticate-via-browser-300x166.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/authenticate-via-browser-520x288.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/authenticate-via-browser-360x199.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/authenticate-via-browser-250x138.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/authenticate-via-browser-100x55.webp 100w" sizes="auto, (max-width: 604px) 100vw, 604px" /></figure></div>



<p class="wp-block-paragraph">Meanwhile, our authorization server will provide the a login form. Below you can see my Keycloak login screen where I authenticate as an example user of my realm:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="788" height="615" src="https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing.webp" alt="authenticating Postman in Keycloak via browser screenshot" class="wp-image-9143" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing.webp 788w, https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing-300x234.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing-768x599.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing-700x546.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing-520x406.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing-360x281.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing-250x195.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/sign-in-to-keep-growing-100x78.webp 100w" sizes="auto, (max-width: 788px) 100vw, 788px" /></figure></div>



<p class="wp-block-paragraph">After successful authentication, we will see the following screen for a few seconds:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="599" height="353" src="https://keepgrowing.in/wp-content/uploads/2022/02/successful-authentication.webp" alt="successful Postman authorization in Keycloak message" class="wp-image-9144" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/successful-authentication.webp 599w, https://keepgrowing.in/wp-content/uploads/2022/02/successful-authentication-300x177.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/successful-authentication-520x306.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/successful-authentication-360x212.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/successful-authentication-250x147.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/successful-authentication-100x59.webp 100w" sizes="auto, (max-width: 599px) 100vw, 599px" /></figure></div>



<p class="wp-block-paragraph">As a result, a new <code>spring-boot-example token</code> value is available in the <code>Manage Access Token</code> window. Click the <code>Use Token</code> button:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="802" height="426" src="https://keepgrowing.in/wp-content/uploads/2022/02/use-token.webp" alt="authorization token available in Postman" class="wp-image-9145" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/use-token.webp 802w, https://keepgrowing.in/wp-content/uploads/2022/02/use-token-300x159.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/use-token-768x408.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/use-token-700x372.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/use-token-520x276.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/use-token-360x191.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/use-token-250x133.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/use-token-100x53.webp 100w" sizes="auto, (max-width: 802px) 100vw, 802px" /></figure></div>



<p class="wp-block-paragraph">You&#8217;ll see the token value in the <code>Current Token</code> section:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="798" height="254" src="https://keepgrowing.in/wp-content/uploads/2022/02/current-token.webp" alt="current access token" class="wp-image-9146" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/current-token.webp 798w, https://keepgrowing.in/wp-content/uploads/2022/02/current-token-300x95.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/current-token-768x244.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/current-token-700x223.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/current-token-520x166.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/current-token-360x115.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/current-token-250x80.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/current-token-100x32.webp 100w" sizes="auto, (max-width: 798px) 100vw, 798px" /></figure></div>



<p class="wp-block-paragraph">Furthermore, we can verify the token payload by decoding it with <a href="https://jwt.io/" target="_blank" rel="noreferrer noopener">jwt.io</a>:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1238" height="860" src="https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded.webp" alt="token used to authorize Postman requests in Keycloak" class="wp-image-9232" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded.webp 1238w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-300x208.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-1024x711.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-768x534.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-700x486.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-520x361.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-360x250.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-250x174.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/token-decoded-100x69.webp 100w" sizes="auto, (max-width: 1238px) 100vw, 1238px" /></figure></div>



<h3 class="wp-block-heading" id="make-the-token-available-in-all-requests">Make the token available in all requests</h3>



<p class="wp-block-paragraph">To make this token accessible in all requests in my collection, I&#8217;m going to select the <code>Inherit auth from parent</code> option in the request <code>Authorization</code> tab:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1464" height="420" src="https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent.webp" alt="inherited authorization config in a single request" class="wp-image-9149" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent.webp 1464w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-300x86.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-1024x294.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-768x220.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-700x201.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-520x149.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-360x103.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-250x72.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/inherit-from-parent-100x29.webp 100w" sizes="auto, (max-width: 1464px) 100vw, 1464px" /></figure></div>



<p class="wp-block-paragraph">As a result, Keycloak will authorize all requests with this config from my Postman collection.</p>



<h2 class="wp-block-heading" id="update-and-manage-access-tokens">Update and manage Access Tokens</h2>



<p class="wp-block-paragraph">When the token expires, generate a new value. Just edit your collection, go to the <code>Authorization</code> tab, click the <code>Generate New Access Token</code> button, then click the <code>Use Token</code> button and finally click the <code>Update</code> button:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="521" height="245" src="https://keepgrowing.in/wp-content/uploads/2022/02/update.webp" alt="update Keycloak access token in Postman collection" class="wp-image-9247" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/update.webp 521w, https://keepgrowing.in/wp-content/uploads/2022/02/update-300x141.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/update-360x169.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/update-250x118.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/update-100x47.webp 100w" sizes="auto, (max-width: 521px) 100vw, 521px" /></figure></div>



<p class="wp-block-paragraph">To update the token or to overwrite the collection config for only one request, go to the <code>Authorization</code> tab of that request and select the <code>OAuth 2.0</code> for the authorization type. You&#8217;ll be able to generate a new token or redefine the configuration values:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1541" height="399" src="https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped.webp" alt="access token config to authorize a Postman request in Keycloak" class="wp-image-9170" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped.webp 1541w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-300x78.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-1024x265.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-768x199.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-1536x398.webp 1536w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-700x181.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-520x135.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-360x93.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-250x65.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/authorization-request-level-cropped-100x26.webp 100w" sizes="auto, (max-width: 1541px) 100vw, 1541px" /></figure></div>



<p class="wp-block-paragraph">Furthermore, you can select a specific token value from the <code>Available Tokens</code> dropdown:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1541" height="329" src="https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1.webp" alt="available tokens" class="wp-image-9175" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1.webp 1541w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-300x64.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-1024x219.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-768x164.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-1536x328.webp 1536w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-700x149.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-520x111.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-360x77.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-250x53.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/available-tokens-1-100x21.webp 100w" sizes="auto, (max-width: 1541px) 100vw, 1541px" /></figure>



<p class="wp-block-paragraph">Finally, you can remove some tokens by clicking the<code> Manage Tokens</code> option:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="210" height="165" src="https://keepgrowing.in/wp-content/uploads/2022/02/remove-expired.webp" alt="removing access tokens" class="wp-image-9176" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/remove-expired.webp 210w, https://keepgrowing.in/wp-content/uploads/2022/02/remove-expired-100x79.webp 100w" sizes="auto, (max-width: 210px) 100vw, 210px" /></figure></div>



<h2 class="wp-block-heading" id="prerequisites">Why not other flows</h2>



<p class="wp-block-paragraph">You can still find tutorials on setting up other Authorization Flows. However, here are the documented reasons why I don&#8217;t use them in my application.</p>



<h3 class="wp-block-heading" id="prerequisites">Why not Implicit flow</h3>



<p class="wp-block-paragraph">This is the easiest flow. Nonetheless, it comes with some severe security vulnerabilities:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>The implicit grant (…) and other response types causing the authorization server to issue access tokens in the authorization response are vulnerable to access token leakage and access token replay (…).<br>Moreover, no viable mechanism exists to cryptographically bind access tokens issued in the authorization response to a certain client (…). This makes replay detection for such access tokens at resource servers impossible.<br>In order to avoid these issues, clients SHOULD NOT use the implicit grant (…), unless access token injection in the authorization response is prevented and the aforementioned token leakage vectors are mitigated.</p><cite><a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-2.1.2" target="_blank" rel="noreferrer noopener">https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-2.1.2</a></cite></blockquote>



<p class="wp-block-paragraph">The vulnerabilities were described in depth in the <code>Implement the OAuth 2.0 Authorization Code with PKCE Flow</code> post on the Okta blog:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Notice that after you authenticate, the Authorization Server (like Google) responds directly with tokens. This means that the tokens are in your browser’s address bar as a result of the redirect. That’s problematic since Google can’t definitively know that your browser (the intended recipient) actually received the response. It’s also problematic because modern browsers can do browser history syncing and they support browser extensions that could be actively scanning for tokens in the browser address bar. Leaking tokens is a big security risk.</p><cite><a href="https://developer.okta.com/blog/2019/08/22/okta-authjs-pkce#why-you-should-never-use-the-implicit-flow-again" target="_blank" rel="noreferrer noopener">https://developer.okta.com/blog/2019/08/22/okta-authjs-pkce#why-you-should-never-use-the-implicit-flow-again</a></cite></blockquote>



<p class="wp-block-paragraph">As a result of these security concerns, the Implicit Flow is officially deprecated:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Please note that as of 2020, the implicit flow is about to be deprecated by OAuth 2.0 Security Best Current Practice. Recommended for most use case is Authorization Code Grant flow with PKCE.</p><cite><a href="https://spec.openapis.org/oas/latest.html#security-scheme-object" target="_blank" rel="noreferrer noopener">https://spec.openapis.org/oas/latest.html#security-scheme-object</a></cite></blockquote>



<h3 class="wp-block-heading" id="prerequisites">Why not Password flow</h3>



<p class="wp-block-paragraph">Another convenient flow that we can configure in Postman, the  <code>Password Credentials</code> Grant Type, also comes with an increased risk of attack:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>The resource owner password credentials grant MUST NOT be used. This grant type insecurely exposes the credentials of the resource owner to the client. Even if the client is benign, this results in an increased attack surface (credentials can leak in more places than just the authorization server) and users are trained to enter their credentials in places other than the authorization server.</p><cite><a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-13#section-3.4" target="_blank" rel="noreferrer noopener">https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-13#section-3.4</a></cite></blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Because the client application has to collect the user&#8217;s password and send it to the authorization server, it is not recommended that this grant be used at all anymore.</p><cite><a href="https://oauth.net/2/grant-types/password/" target="_blank" rel="noreferrer noopener">https://oauth.net/2/grant-types/password/</a></cite></blockquote>



<h2 class="wp-block-heading" id="prerequisites">More on how to authorize Postman requests in Keycloak</h2>



<ul class="wp-block-list"><li><a href="https://learning.postman.com/docs/sending-requests/authorization/" target="_blank" rel="noreferrer noopener">Authorizing requests</a>, <a href="https://learning.postman.com/docs/sending-requests/authorization/#oauth-20" target="_blank" rel="noreferrer noopener">OAuth 2.0 authorization type</a>, <a href="https://learning.postman.com/docs/sending-requests/authorization/#requesting-an-oauth-20-token" target="_blank" rel="noreferrer noopener">Requesting an OAuth 2.0 token</a> in the Postman documentation and the example<a href="https://documenter.getpostman.com/view/1559645/Szzhcxzz" target="_blank" rel="noreferrer noopener"> collection that documents a few OAuth 2.0 authorization flows</a>.</li><li><a href="https://blog.postman.com/pkce-oauth-how-to/" target="_blank" rel="noreferrer noopener">OAuth 2.0: Implicit Flow is Dead, Try PKCE Instead</a> and <a href="https://aaronparecki.com/oauth-2-simplified/" target="_blank" rel="noreferrer noopener">OAuth 2 Simplified</a> articles.</li><li><a href="https://datatracker.ietf.org/doc/html/rfc7636" target="_blank" rel="noreferrer noopener">Proof Key for Code Exchange by OAuth Public Clients</a></li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@elevate?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">ELEVATE</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/man-handing-over-a-beer-from-the-cooler-3009777/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/">Kecloak in Docker #7 – How to authorize requests via Postman</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/tools/kecloak-in-docker-7-how-to-authorize-requests-via-postman/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">9109</post-id>	</item>
		<item>
		<title>How to add X-XSRF-TOKEN header to Postman requests</title>
		<link>https://keepgrowing.in/tools/how-to-add-x-xsrf-token-header-to-postman-requests/</link>
					<comments>https://keepgrowing.in/tools/how-to-add-x-xsrf-token-header-to-postman-requests/#comments</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Sat, 05 Feb 2022 11:55:18 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[CSRF]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Invalid CSRF token]]></category>
		<category><![CDATA[Postman]]></category>
		<category><![CDATA[X-XSRF-TOKEN]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=9047</guid>

					<description><![CDATA[<p>When an API is secured against CSRF attacks, we must ensure that our clients&#8217; requests are adjusted to the security requirements. Learn how to successfully call an API that uses the Cookie-to-header token approach by adding the X-XSRF-TOKEN header to Postman requests. Debugging the “Invalid CSRF token” error We get the Invalid CSRF token error when an API has csrf protection enabled and our request doesn&#8217;t contain the required data. The security configuration regarding the csrf protection in my example Spring Boot project looks like this: The Spring documentation describes the CookieCsrfTokenRepository as follows: A CsrfTokenRepository that persists the CSRF token in a cookie named &#8220;XSRF-TOKEN&#8221; and reads from the header &#8220;X-XSRF-TOKEN&#8221; https://docs.spring.io/spring-security/site/docs/5.0.13.RELEASE/api/index.html?org/springframework/security/web/csrf/CookieCsrfTokenRepository.html As a result, the token will be present in the API responses as seen in the screenshot below: Consequently, when I&#8217;m sending a POST request with no value provided in the required header, I get the 403 Forbidden in response. The exact error is specified in the application logs: In a Spring Boot application, we can debug the actual value that is checked in the CsrfFilter class: In my case, the actual value is null. So I need to add the X-XSRF-TOKEN header to my Postman POST requests. Add XSRF token to Postman requests I&#8217;m going to configure my Postman collection to get the current token from each request and save it as an environment variable. Then, I will use this variable as the header value for my POST calls. Save the token value as an environment variable To read the value of the cookie, we&#8217;re going to execute a short JavaScript code in Postman. The sample collection I&#8217;m using for this article is in my public Postman workspace and is part of my keycloak-spring-boot project. If you want to test my code locally (it requires Docker for running a Keycloak instance), visit the project repository on GitHub and follow the directions in the README.md file. For all requests First, I&#8217;m going to place the js code in the Collection testing space. As we can read in the documentation: A test script associated with a collection will run after every request in the collection. https://learning.postman.com/docs/writing-scripts/test-scripts/#testing-collections-and-folders This way, I won&#8217;t have to add the script to every POST request I may create in this collection in the future. I&#8217;m going to edit my example keycloak-spring-boot collection: Then, I&#8217;m going to add the following code to the Tests tab: You can see the result in the screenshot below: Finally, I&#8217;m going to save the changes to the collection by clicking the Update button. For a single request Alternatively, I can only read the cookie after a selected request. To achieve this, I will need to add the js code in the request-specific test space and click the Save button. In summary, the configuration of a single request will look like this: In this case, we must remember to add the js code to any future POST request as well. Add the header First, I&#8217;m going to verify that the value is actually available as an environment variable in Postman after running my request. Therefore, I&#8217;m going to execute the request, click on the Environment quick look button (the eye icon) and look for the xsrf-token variable as shown in the screenshot below: Now I&#8217;m going to add a new header to my request, with the following data: Key: X-XSRF-TOKEN, Value: {{xsrf-token}}. We can see the result in the screenshot below: Verify the configuration Finally, I can make my POST request with the certainty that it will work successfully: Troubleshooting What to check when API calls don&#8217;t work as planned? 403 Forbidden response status The JavaScript code we add will only run after a request. Therefore, we will get 403 on the first API call since the cookie value is not yet set to a variable. However, subsequent requests will have the appropriate value in the header. Is the {{xsrf-token}} variable set in Postman environment? You can see its current value in the Environment quick look or by hovering over the variable. Select the proper environment (localhost in my example) and make sure that the value is not empty. Can you check API logs or debug the actual verified header value? If the value is null, the header is empty. Remember that even if we add the script to a collection-specific test space, we need to manually add the X-XSRF-TOKEN header to each POST request. More on complying with the CSRF requirements How do I send spring csrf token from Postman rest client? Moreover, you can learn how to get a list of cookies associated with a request in the Scripting with request cookies docs. Read the Defining variables in scripts if want to set variables programmatically in your request scripts. Difference between CSRF and X-CSRF-Token. What is the difference between X-XSRF-TOKEN and X-CSRF-TOKEN? Spring Security Reference Guide on Cross Site Request Forgery. Fix “Invalid CSRF token” error – add the XSRF-TOKEN header in Angular. Postman Pre-Request script to append CSRF token in header for POST requests in Laravel Sanctum authenticated SPA. Photo by&#160;Andrea Piacquadio&#160;from&#160;Pexels</p>
<p>The post <a href="https://keepgrowing.in/tools/how-to-add-x-xsrf-token-header-to-postman-requests/">How to add X-XSRF-TOKEN header to Postman requests</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When an API is secured against <a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html" target="_blank" rel="noreferrer noopener">CSRF</a> attacks, we must ensure that our clients&#8217; requests are adjusted to the security requirements. Learn how to successfully call an API that uses the <a href="https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-header_token" target="_blank" rel="noreferrer noopener">Cookie-to-header token</a> approach by adding the X-XSRF-TOKEN header to Postman requests.</p>



<span id="more-9047"></span>



<h2 class="wp-block-heading" id="more-on-setting-x-xsrf-token-in-postman">Debugging the “Invalid CSRF token” error</h2>



<p class="wp-block-paragraph">We get the <code>Invalid CSRF token</code> error when an API has csrf protection enabled and our request doesn&#8217;t contain the required data. The <a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator.endpoints.security.csrf" target="_blank" rel="noreferrer noopener">security configuration regarding the csrf protection</a> in my example Spring Boot project looks like this:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">public static void configureApiSecurity(HttpSecurity http) throws Exception {
        http
                .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
…</pre></div>



<p class="wp-block-paragraph">The Spring documentation describes the <code>CookieCsrfTokenRepository</code> as follows:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>A CsrfTokenRepository that persists the CSRF token in a cookie named &#8220;XSRF-TOKEN&#8221; and reads from the header &#8220;X-XSRF-TOKEN&#8221;</p><cite><a href="https://docs.spring.io/spring-security/site/docs/5.0.13.RELEASE/api/index.html?org/springframework/security/web/csrf/CookieCsrfTokenRepository.html" target="_blank" rel="noreferrer noopener">https://docs.spring.io/spring-security/site/docs/5.0.13.RELEASE/api/index.html?org/springframework/security/web/csrf/CookieCsrfTokenRepository.html</a></cite></blockquote>



<p class="wp-block-paragraph">As a result, the token will be present in the API responses as seen in the screenshot below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="614" height="267" src="https://keepgrowing.in/wp-content/uploads/2022/02/cookie-value-1.webp" alt="XSRF-TOKEN send in a cookie with Postman" class="wp-image-9067" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/cookie-value-1.webp 614w, https://keepgrowing.in/wp-content/uploads/2022/02/cookie-value-1-300x130.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/cookie-value-1-520x226.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/cookie-value-1-360x157.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/cookie-value-1-250x109.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/cookie-value-1-100x43.webp 100w" sizes="auto, (max-width: 614px) 100vw, 614px" /></figure></div>



<p class="wp-block-paragraph">Consequently, when I&#8217;m sending a POST request with no value provided in the required header, I get the 403 Forbidden in response. The exact error is specified in the application logs:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">DEBUG 11528 --- [nio-8080-exec-3] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8080/api/products
DEBUG 11528 --- [nio-8080-exec-3] o.s.s.w.access.AccessDeniedHandlerImpl   : Responding with 403 status code</pre></div>



<p class="wp-block-paragraph">In a Spring Boot application, we can debug the actual value that is checked in the <a href="https://github.com/spring-projects/spring-security/blob/main/web/src/main/java/org/springframework/security/web/csrf/CsrfFilter.java" target="_blank" rel="noreferrer noopener">CsrfFilter</a> class:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1353" height="571" src="https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs.webp" alt="debugging Spring CsrfFilter.java class" class="wp-image-9053" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs.webp 1353w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-300x127.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-1024x432.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-768x324.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-700x295.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-520x219.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-360x152.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-250x106.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/csrf-filter-and-logs-100x42.webp 100w" sizes="auto, (max-width: 1353px) 100vw, 1353px" /></figure></div>



<p class="wp-block-paragraph">In my case, the actual value is null. So I need to add the X-XSRF-TOKEN header to my Postman POST requests.</p>



<h2 class="wp-block-heading" id="more-on-setting-x-xsrf-token-in-postman">Add XSRF token to Postman requests</h2>



<p class="wp-block-paragraph">I&#8217;m going to configure my Postman collection to get the current token from each request and save it as an environment variable. Then, I will use this variable as the header value for my POST calls.</p>



<h3 class="wp-block-heading" id="more-on-setting-x-xsrf-token-in-postman">Save the token value as an environment variable</h3>



<p class="wp-block-paragraph">To read the value of the cookie, we&#8217;re going to execute a short JavaScript code in Postman.</p>



<p class="wp-block-paragraph">The sample collection I&#8217;m using for this article is in my public Postman workspace and is part of my <code>keycloak-spring-boot</code> project. If you want to test my code locally (it requires Docker for running a Keycloak instance), visit the <a href="https://github.com/little-pinecone/keycloak-spring-boot" target="_blank" rel="noreferrer noopener">project repository on GitHub</a> and follow the directions in the README.md file.</p>



<h4 class="wp-block-heading" id="for-all-requests">For all requests</h4>



<p class="wp-block-paragraph">First, I&#8217;m going to place the js code in the Collection testing space. As we can read in the documentation:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>A test script associated with a collection will run after every request in the collection.</p><cite><a href="https://learning.postman.com/docs/writing-scripts/test-scripts/#testing-collections-and-folders" target="_blank" rel="noreferrer noopener">https://learning.postman.com/docs/writing-scripts/test-scripts/#testing-collections-and-folders</a></cite></blockquote>



<p class="wp-block-paragraph">This way, I won&#8217;t have to add the script to every POST request I may create in this collection in the future.</p>



<p class="wp-block-paragraph">I&#8217;m going to edit my example <code>keycloak-spring-boot</code> collection:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="979" height="375" src="https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection.webp" alt="editing a Postman collection" class="wp-image-9055" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection.webp 979w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-300x115.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-768x294.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-700x268.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-520x199.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-360x138.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-250x96.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/edit-collection-100x38.webp 100w" sizes="auto, (max-width: 979px) 100vw, 979px" /></figure></div>



<p class="wp-block-paragraph">Then, I&#8217;m going to add the following code to the <code>Tests</code> tab:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">var xsrfCookie = pm.cookies.get("XSRF-TOKEN");
pm.environment.set('xsrf-token', xsrfCookie);</pre></div>



<p class="wp-block-paragraph">You can see the result in the screenshot below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="869" height="318" src="https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests.webp" alt="adding code for extracting the xsrf token value from all responses in Postman" class="wp-image-9056" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests.webp 869w, https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests-300x110.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests-768x281.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests-700x256.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests-520x190.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests-360x132.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests-250x91.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/add-code-to-tests-100x37.webp 100w" sizes="auto, (max-width: 869px) 100vw, 869px" /></figure></div>



<p class="wp-block-paragraph">Finally, I&#8217;m going to save the changes to the collection by clicking the <code>Update</code> button.</p>



<h4 class="wp-block-heading" id="for-all-requests">For a single request</h4>



<p class="wp-block-paragraph">Alternatively, I can only read the cookie after a selected request. To achieve this, I will need to add the js code in the request-specific test space and click the <code>Save</code> button. In summary, the configuration of a single request will look like this:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="925" height="245" src="https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request.webp" alt="adding code for extracting the xsrf token value from a single response in Postman" class="wp-image-9073" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request.webp 925w, https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request-300x79.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request-768x203.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request-700x185.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request-520x138.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request-360x95.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request-250x66.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/save-test-single-request-100x26.webp 100w" sizes="auto, (max-width: 925px) 100vw, 925px" /></figure></div>



<p class="wp-block-paragraph">In this case, we must remember to add the js code to any future POST request as well.</p>



<h3 class="wp-block-heading" id="more-on-setting-x-xsrf-token-in-postman">Add the header</h3>



<p class="wp-block-paragraph">First, I&#8217;m going to verify that the value is actually available as an <a href="https://learning.postman.com/docs/sending-requests/managing-environments/#accessing-environments" target="_blank" rel="noreferrer noopener">environment variable in Postman</a> after running my request. Therefore, I&#8217;m going to execute the request, click on the <code>Environment quick look</code> button (the eye icon) and look for the <code>xsrf-token</code> variable as shown in the screenshot below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="880" height="314" src="https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables.webp" alt="token value available as an environment variable" class="wp-image-9077" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables.webp 880w, https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables-300x107.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables-768x274.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables-700x250.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables-520x186.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables-360x128.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables-250x89.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/value-in-env-variables-100x36.webp 100w" sizes="auto, (max-width: 880px) 100vw, 880px" /></figure></div>



<p class="wp-block-paragraph">Now I&#8217;m going to add a new header to my request, with the following data:</p>



<ul class="wp-block-list"><li>Key: <code>X-XSRF-TOKEN</code>,</li><li>Value: <code>{{xsrf-token}}</code>.</li></ul>



<p class="wp-block-paragraph">We can see the result in the screenshot below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="809" height="344" src="https://keepgrowing.in/wp-content/uploads/2022/02/add-header.webp" alt="X-XSRF-TOKEN header added to a Postman POST request" class="wp-image-9057" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/add-header.webp 809w, https://keepgrowing.in/wp-content/uploads/2022/02/add-header-300x128.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/add-header-768x327.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/add-header-700x298.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/add-header-520x221.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/add-header-360x153.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/add-header-250x106.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/add-header-100x43.webp 100w" sizes="auto, (max-width: 809px) 100vw, 809px" /></figure></div>



<h3 class="wp-block-heading" id="more-on-setting-x-xsrf-token-in-postman">Verify the configuration</h3>



<p class="wp-block-paragraph">Finally, I can make my POST request with the certainty that it will work successfully:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1457" height="683" src="https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post.webp" alt="working POST request example" class="wp-image-9058" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post.webp 1457w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-300x141.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-1024x480.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-768x360.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-700x328.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-520x244.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-360x169.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-250x117.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/succesful-post-100x47.webp 100w" sizes="auto, (max-width: 1457px) 100vw, 1457px" /></figure>



<h2 class="wp-block-heading" id="more-on-setting-x-xsrf-token-in-postman">Troubleshooting</h2>



<p class="wp-block-paragraph">What to check when API calls don&#8217;t work as planned?</p>



<h3 class="wp-block-heading" id="403-forbidden-response-status">403 Forbidden response status</h3>



<ul class="wp-block-list"><li>The JavaScript code we add will only run after a request. Therefore, we will get 403 on the first API call since the cookie value is not yet set to a variable. However, subsequent requests will have the appropriate value in the header.</li><li>Is the <code>{{xsrf-token}}</code> variable set in Postman environment? You can see its current value in the <code>Environment quick look</code> or by hovering over the variable. Select the proper environment (<code>localhost</code> in my example) and make sure that the value is not empty.</li><li>Can you check API logs or debug the actual verified header value? If the value is null, the header is empty.</li><li>Remember that even if we add the script to a collection-specific test space, we need to manually add the X-XSRF-TOKEN header to each POST request.</li></ul>



<h2 class="wp-block-heading" id="more-on-setting-x-xsrf-token-in-postman">More on complying with the CSRF requirements</h2>



<ul class="wp-block-list"><li><a href="https://stackoverflow.com/questions/27182701/how-do-i-send-spring-csrf-token-from-postman-rest-client" target="_blank" rel="noreferrer noopener">How do I send spring csrf token from Postman rest client?</a></li><li>Moreover, you can learn how to get a list of cookies associated with a request in the <a href="https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/#scripting-with-request-cookies" target="_blank" rel="noreferrer noopener">Scripting with request cookies</a> docs.</li><li>Read the <a href="https://learning.postman.com/docs/sending-requests/variables/#defining-variables-in-scripts" target="_blank" rel="noreferrer noopener">Defining variables in scripts</a> if want to set variables programmatically in your request scripts.</li><li><a href="https://stackoverflow.com/a/34783845" target="_blank" rel="noreferrer noopener">Difference between CSRF and X-CSRF-Token</a>.</li><li><a href="https://stackoverflow.com/a/56144709" target="_blank" rel="noreferrer noopener">What is the difference between X-XSRF-TOKEN and X-CSRF-TOKEN?</a></li><li><a href="https://docs.spring.io/spring-security/reference/features/exploits/csrf.html" target="_blank" rel="noreferrer noopener">Spring Security Reference Guide on Cross Site Request Forgery</a>.</li><li><a href="https://keepgrowing.in/angular/fix-invalid-csrf-token-error-add-the-xsrf-token-header-in-angular/" target="_blank" rel="noreferrer noopener">Fix “Invalid CSRF token” error – add the XSRF-TOKEN header in Angular</a>.</li><li><a href="https://gist.github.com/janzikmund/3047ba4b7031efbabd7ade115f1e3317" target="_blank" rel="noreferrer noopener">Postman Pre-Request script </a>to append CSRF token in header for POST requests in Laravel Sanctum authenticated SPA.</li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@olly?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Andrea Piacquadio</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/pensive-grandmother-with-granddaughter-having-interesting-conversation-while-cooking-together-in-light-modern-kitchen-3768146/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/tools/how-to-add-x-xsrf-token-header-to-postman-requests/">How to add X-XSRF-TOKEN header to Postman requests</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/tools/how-to-add-x-xsrf-token-header-to-postman-requests/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">9047</post-id>	</item>
		<item>
		<title>Keycloak in Docker #6 – How to import realms from a directory</title>
		<link>https://keepgrowing.in/tools/keycloak-in-docker-6-how-to-import-realms-from-a-directory/</link>
					<comments>https://keepgrowing.in/tools/keycloak-in-docker-6-how-to-import-realms-from-a-directory/#respond</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Thu, 03 Feb 2022 12:04:52 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[user management]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=8982</guid>

					<description><![CDATA[<p>If we want to import multiple Keycloak realms, or realm resources are split into multiple files, we need to execute a directory import at boot time. Fortunately, running a Keycloak service with Docker makes this task easy. Prerequsites Docker Engine and Docker Compose installed on your machine. If this is your first attempt to run Keycloak in Docker, I recommend reading the post Keycloak in Docker # 1 &#8211; How to run Keycloak in a Docker container, as I explained the basic configuration there. You&#8217;ll need at least one realm that was exported to a directory. You can learn how to do it in the Keycloak in Docker #5 – How to export a realm with users and secrets post. Configure importing Keycloak relams from a directory The example Docker Compose configuration used below is available in the https://gist.github.com/little-pinecone/6b52ccd1fc0296b267e810d43fd01f3b GitHub gist. The importance of the naming convention As we can read in the docs: When importing from a directory, the filenames must follow this naming convention: &#60;REALM_NAME&#62;-realm.json. For example, &#8220;acme-roadrunner-affairs-realm.json&#8221; for the realm named &#8220;acme-roadrunner-affairs&#8221;. &#60;REALM_NAME&#62;-users-&#60;INDEX&#62;.json. For example, &#8220;acme-roadrunner-affairs-users-0.json&#8221; for the first user’s file of the realm named &#8220;acme-roadrunner-affairs&#8221;. https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide Make sure the resources for your realms follow this naming convention. Otherwise, some or all of the files may be skipped completely from import. Add a Docker volume for the imported resources First, I&#8217;m going to create a Docker volume to make the import assets available in the /tmp/import directory in the container. Below you&#8217;ll find the relevant configuration from my docker-compose.yml file: Provide the required options when running the container Next, I&#8217;m going to add the minimum configuration required to perform the directory import to my docker-compose.yml file: This configuration will overwrite existing realms by default. For other keycloak.migration.X options, see the official Keycloak documentation on importing and exporting the database. Import a Keycloak realm that has been exported in multiple files Below you can see the starting point for importing my keep-growing realm: To summarize, I have one file with the realm configuration and one with the associated users. With the Docker Compose configuration described in the previous section, I&#8217;m going to start the container using the docker-compose up -d command. As a result, we can see in the screenshot below that the volume with realm resources was mapped properly: Furthermore, the container logs contain entries documenting a successful import: At last, we can examine the imported realm in the Keycloak Admin Console: Import multiple Keycloak realms Below you can see the starting point for importing my keep-growing and Example-Realm realms: To summarize, I have two files, one for each realm. With the Docker Compose configuration described in the previous section, I&#8217;m going to start the container using the docker-compose up -d command. Consequently, we can see in the screenshot below that the volume with realms is available in the container: Furthermore, the container logs contain entries documenting successful imports: Finally, we can examine the imported realm in the Keycloak Admin Console: Read more on Keycloak directory import In addition to this article, see the Keycloak documentation on importing and exporting the database. Additionally, you can visit the How to import Multiple realms in keycloak? and Missing users from Keycloak Realm after import issues on StackOverflow. In case you need to import realm from a single file, see the Keycloak in Docker #2 – How to import a Keycloak realm post. Photo by&#160;Vlada Karpovich&#160;from&#160;Pexels</p>
<p>The post <a href="https://keepgrowing.in/tools/keycloak-in-docker-6-how-to-import-realms-from-a-directory/">Keycloak in Docker #6 – How to import realms from a directory</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If we want to import multiple Keycloak realms, or realm resources are split into multiple files, we need to execute a directory import at boot time. Fortunately, running a Keycloak service with Docker makes this task easy.</p>



<span id="more-8982"></span>



<h2 class="wp-block-heading" id="prerequsites">Prerequsites</h2>



<ul class="wp-block-list"><li><a href="https://docs.docker.com/engine/" target="_blank" rel="noreferrer noopener">Docker Engine</a> and <a href="https://docs.docker.com/compose/install/" target="_blank" rel="noreferrer noopener">Docker Compose</a> installed on your machine.</li><li>If this is your first attempt to run Keycloak in Docker, I recommend reading the post <a href="https://keepgrowing.in/tools/keycloak-in-docker-1-how-to-run-keycloak-in-a-docker-container/" target="_blank" rel="noreferrer noopener">Keycloak in Docker # 1 &#8211; How to run Keycloak in a Docker container</a>, as I explained the basic configuration there.</li><li>You&#8217;ll need at least one realm that was exported to a directory. You can learn how to do it in the <a href="https://keepgrowing.in/tools/keycloak-in-docker-5-how-to-export-a-realm-with-users-and-secrets/" target="_blank" rel="noreferrer noopener">Keycloak in Docker #5 – How to export a realm with users and secrets</a> post.</li></ul>



<h2 class="wp-block-heading" id="import-keycloak-realm-with-multiple-user-files">Configure importing Keycloak relams from a directory</h2>



<p class="wp-block-paragraph">The example Docker Compose configuration used below is available in the <a href="https://gist.github.com/little-pinecone/6b52ccd1fc0296b267e810d43fd01f3b" target="_blank" rel="noreferrer noopener">https://gist.github.com/little-pinecone/6b52ccd1fc0296b267e810d43fd01f3b</a> GitHub gist.</p>



<h3 class="wp-block-heading" id="import-keycloak-realm-with-multiple-user-files">The importance of the naming convention</h3>



<p class="wp-block-paragraph">As we can read in the docs:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>When importing from a directory, the filenames must follow this naming convention:</p><p>&lt;REALM_NAME&gt;-realm.json. For example, &#8220;acme-roadrunner-affairs-realm.json&#8221; for the realm named &#8220;acme-roadrunner-affairs&#8221;.</p><p>&lt;REALM_NAME&gt;-users-&lt;INDEX&gt;.json. For example, &#8220;acme-roadrunner-affairs-users-0.json&#8221; for the first user’s file of the realm named &#8220;acme-roadrunner-affairs&#8221;.</p><cite><a href="https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide">https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide</a></cite></blockquote>



<p class="wp-block-paragraph">Make sure the resources for your realms follow this naming convention. Otherwise, some or all of the files may be skipped completely from import.</p>



<h3 class="wp-block-heading" id="add-a-docker-volume-for-the-imported-resources">Add a Docker volume for the imported resources</h3>



<p class="wp-block-paragraph">First, I&#8217;m going to create a Docker <a href="https://docs.docker.com/storage/volumes/" target="_blank" rel="noreferrer noopener">volume</a> to make the import assets available in the <code>/tmp/import</code> directory in the container. Below you&#8217;ll find the relevant configuration from my <code>docker-compose.yml</code> file:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">version: '3.3'
services:
  keycloak:
    …
    volumes:
      - ./keycloak/realms/import:/tmp/import
    …</pre></div>



<h3 class="wp-block-heading" id="provide-the-required-options-when-running-the-container">Provide the required options when running the container</h3>



<p class="wp-block-paragraph">Next, I&#8217;m going to add the minimum configuration required to perform the directory import to my <code>docker-compose.yml</code> file:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">services:
  keycloak:
    …
    volumes:
       …
    command:
      - "-Dkeycloak.migration.action=import"
      - "-Dkeycloak.migration.provider=dir"
      - "-Dkeycloak.migration.dir=/tmp/import"</pre></div>



<p class="wp-block-paragraph">This configuration will overwrite existing realms by default. For other <code>keycloak.migration.X</code> options, see the official Keycloak documentation on <a href="https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide" target="_blank" rel="noreferrer noopener">importing and exporting the database</a>.</p>



<h2 class="wp-block-heading" id="import-keycloak-realm-with-multiple-user-files">Import a Keycloak realm that has been exported in multiple files</h2>



<p class="wp-block-paragraph">Below you can see the starting point for importing my <code>keep-growing</code> realm:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="340" height="206" src="https://keepgrowing.in/wp-content/uploads/2022/02/import-resources-locally-user-files.webp" alt="realm resources for directory import locally" class="wp-image-8991" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/import-resources-locally-user-files.webp 340w, https://keepgrowing.in/wp-content/uploads/2022/02/import-resources-locally-user-files-300x182.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/import-resources-locally-user-files-250x151.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/import-resources-locally-user-files-100x61.webp 100w" sizes="auto, (max-width: 340px) 100vw, 340px" /></figure></div>



<p class="wp-block-paragraph">To summarize, I have one file with the realm configuration and one with the associated users. With the Docker Compose configuration described in the previous section, I&#8217;m going to start the container using the <code>docker-compose up -d</code> command.</p>



<p class="wp-block-paragraph">As a result, we can see in the screenshot below that the volume with realm resources was mapped properly:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="654" height="248" src="https://keepgrowing.in/wp-content/uploads/2022/02/import-files-in-container.webp" alt="realm resources for directory import in the container" class="wp-image-8993" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/import-files-in-container.webp 654w, https://keepgrowing.in/wp-content/uploads/2022/02/import-files-in-container-300x114.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/import-files-in-container-520x197.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/import-files-in-container-360x137.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/import-files-in-container-250x95.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/import-files-in-container-100x38.webp 100w" sizes="auto, (max-width: 654px) 100vw, 654px" /></figure></div>



<p class="wp-block-paragraph">Furthermore, the container logs contain entries documenting a successful import:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">INFO  [org.keycloak.exportimport.dir.DirImportProvider] (ServerService Thread Pool -- 62) Importing from directory /tmp/import
…
INFO  [org.keycloak.services] (ServerService Thread Pool -- 62) KC-SERVICES0050: Initializing master realm
INFO  [org.keycloak.services] (ServerService Thread Pool -- 56) KC-SERVICES0030: Full model import requested. Strategy: OVERWRITE_EXISTING
INFO  [org.keycloak.exportimport.util.ImportUtils] (ServerService Thread Pool -- 56) Realm 'keep-growing' imported
INFO  [org.keycloak.exportimport.dir.DirImportProvider] (ServerService Thread Pool -- 56) Imported users from /tmp/import/keep-growing-users-0.json
INFO  [org.keycloak.services] (ServerService Thread Pool -- 56) KC-SERVICES0032: Import finished successfully</pre></div>



<p class="wp-block-paragraph">At last, we can examine the imported realm in the <a href="https://www.keycloak.org/docs/16.1/server_admin/#using-the-admin-console">Keycloak Admin Console</a>:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1197" height="390" src="https://keepgrowing.in/wp-content/uploads/2022/02/imported-users.webp" alt="users imported to the keep-growing realm" class="wp-image-9000" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/imported-users.webp 1197w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-300x98.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-1024x334.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-768x250.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-700x228.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-520x169.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-360x117.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-250x81.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/imported-users-100x33.webp 100w" sizes="auto, (max-width: 1197px) 100vw, 1197px" /></figure></div>



<h2 class="wp-block-heading" id="import-keycloak-realm-with-multiple-user-files">Import multiple Keycloak realms</h2>



<p class="wp-block-paragraph">Below you can see the starting point for importing my <code>keep-growing</code> and <code>Example-Realm</code> realms:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="319" height="208" src="https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-locally-1.webp" alt="realms for directory import locally" class="wp-image-9010" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-locally-1.webp 319w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-locally-1-300x196.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-locally-1-250x163.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-locally-1-100x65.webp 100w" sizes="auto, (max-width: 319px) 100vw, 319px" /></figure></div>



<p class="wp-block-paragraph">To summarize, I have two files, one for each realm. With the Docker Compose configuration described in the previous section, I&#8217;m going to start the container using the <code>docker-compose up -d</code> command.</p>



<p class="wp-block-paragraph">Consequently, we can see in the screenshot below that the volume with realms is available in the container:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="646" height="238" src="https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-container.webp" alt="realms for directory import in the container" class="wp-image-9011" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-container.webp 646w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-container-300x111.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-container-520x192.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-container-360x133.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-container-250x92.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/import-many-realms-container-100x37.webp 100w" sizes="auto, (max-width: 646px) 100vw, 646px" /></figure></div>



<p class="wp-block-paragraph">Furthermore, the container logs contain entries documenting successful imports:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">INFO  [org.keycloak.exportimport.dir.DirImportProvider] (ServerService Thread Pool -- 62) Importing from directory /tmp/import
…
INFO  [org.keycloak.services] (ServerService Thread Pool -- 62) KC-SERVICES0050: Initializing master realm
INFO  [org.keycloak.services] (ServerService Thread Pool -- 62) KC-SERVICES0030: Full model import requested. Strategy: OVERWRITE_EXISTING
INFO  [org.keycloak.exportimport.util.ImportUtils] (ServerService Thread Pool -- 62) Realm 'keep-growing' imported
INFO  [org.keycloak.exportimport.util.ImportUtils] (ServerService Thread Pool -- 62) Realm 'Example-Realm' imported
INFO  [org.keycloak.services] (ServerService Thread Pool -- 62) KC-SERVICES0032: Import finished successfully</pre></div>



<p class="wp-block-paragraph">Finally, we can examine the imported realm in the <a href="https://www.keycloak.org/docs/16.1/server_admin/#using-the-admin-console">Keycloak Admin Console</a>:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="572" height="285" src="https://keepgrowing.in/wp-content/uploads/2022/02/multipel-realms-in-ui.webp" alt="multiple realms imported to Keycloak" class="wp-image-9003" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/multipel-realms-in-ui.webp 572w, https://keepgrowing.in/wp-content/uploads/2022/02/multipel-realms-in-ui-300x149.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/multipel-realms-in-ui-520x259.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/multipel-realms-in-ui-360x179.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/multipel-realms-in-ui-250x125.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/multipel-realms-in-ui-100x50.webp 100w" sizes="auto, (max-width: 572px) 100vw, 572px" /></figure></div>



<h2 class="wp-block-heading" id="import-keycloak-realm-with-multiple-user-files">Read more on Keycloak directory import</h2>



<ul class="wp-block-list"><li>In addition to this article, see the Keycloak documentation on <a href="https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide" target="_blank" rel="noreferrer noopener">importing and exporting the database</a>.</li><li>Additionally, you can visit the <a href="https://stackoverflow.com/a/70961047/7995881" target="_blank" rel="noreferrer noopener">How to import Multiple realms in keycloak?</a> and <a href="https://stackoverflow.com/a/70961646/7995881" target="_blank" rel="noreferrer noopener">Missing users from Keycloak Realm after import</a> issues on StackOverflow.</li><li>In case you need to import realm from a single file, see the <a href="https://keepgrowing.in/tools/keycloak-in-docker-2-how-to-import-a-keycloak-realm/" target="_blank" rel="noreferrer noopener">Keycloak in Docker #2 – How to import a Keycloak realm</a> post.</li></ul>



<p class="has-text-align-center wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@vlada-karpovich?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Vlada Karpovich</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/a-woman-listening-on-her-headphones-while-packing-7365317/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/tools/keycloak-in-docker-6-how-to-import-realms-from-a-directory/">Keycloak in Docker #6 – How to import realms from a directory</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/tools/keycloak-in-docker-6-how-to-import-realms-from-a-directory/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8982</post-id>	</item>
		<item>
		<title>Keycloak in Docker #5 – How to export a realm with users and secrets</title>
		<link>https://keepgrowing.in/tools/keycloak-in-docker-5-how-to-export-a-realm-with-users-and-secrets/</link>
					<comments>https://keepgrowing.in/tools/keycloak-in-docker-5-how-to-export-a-realm-with-users-and-secrets/#comments</comments>
		
		<dc:creator><![CDATA[little_pinecone]]></dc:creator>
		<pubDate>Wed, 02 Feb 2022 11:18:13 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[user management]]></category>
		<guid isPermaLink="false">https://keepgrowing.in/?p=8800</guid>

					<description><![CDATA[<p>Running a Keycloak service in a Docker container allows us to share its configuration across multiple environments. However, we can also export an entire Keycloak realm in case we need any backups or data transfer between servers. Prerequisites Docker Engine and Docker Compose installed on your machine. If this is your first attempt to run Keycloak in Docker, I recommend reading the post Keycloak in Docker # 1 &#8211; How to run Keycloak in a Docker container as I explained the basic configuration there. For reference, below you&#8217;ll find the resulting directory tree for this example: In short, my goal is to get the export directory containing realm resources (in this case, the keep-growing-realm.json file). Thanks to this, I&#8217;ll be able to backup or recreate a complete realm whenever I need to. Why not export with Keycloak Admin console? The Keycloak Admin Console provides an easy way to export a realm. However, as you can see in the screenshot below, not all resources can be exported with this method: The realm-export.json file produced with this technique won&#8217;t contain user data. In addition, client secrets will be masked. Although this approach might be appropriate in some use cases, we won&#8217;t be able to recreate the same instance using only this file. If we want to get realm data suitable for backups or cross server migration, we need to run a boot-time export. My example Keycloak realm I have my keep-growing realm with the following users: Furthermore, the realm contains the spring-boot-example-app client. It has the confidential access type and a secret, as you can see in the screenshot below: At the end of this article, I will verify that the users and the secret are properly exported. How to export all resources from a Keycloak realm I&#8217;m going to use a volume to map exported data between the container and my machine. Next, I will show you how to export the data with a command or automatically when running the container. Finally, I&#8217;m going to verify if the export was successful. Add a volume for exported resources First, we need to start our container with a volume that will hold exported data. Therefore, I&#8217;m going to map the ./keycloak/realms/export folder on my machine to the /tmp/export directory in the keycloak service. Below you&#8217;ll find my docker-compose.yml file: I&#8217;m using my default environmental variables defined in the following .env file: Now I&#8217;m going to start the service with the docker-compose up -d command. As we can see in the following screenshot, the volume is properly created and mapped: Obviously, the /tmp/export directory inside the dockerized Keycloak instance is empty as we still need to export our realm: Keycloak export options explained Let me introduce the properties that we&#8217;re going to use: Djboss.socket.binding.port-offset, we want to run the export on a different port than Keycloak itself. By default, the jboss server in my kecyloak instance uses the 9990 port. Therefore, providing e.g. 100 as a value here will result in the command using the 10090 port. Dkeycloak.migration.action, we specify what we want to do. Available options: export, import. Dkeycloak.migration.provider, we define how we want the data. Available options are: singleFile, if we want to export data into a file dir, if we want to export data into a directory. Dkeycloak.migration.realmName, realm for export. Don&#8217;t specify this parameter if you want to export all realms. Dkeycloak.migration.usersExportStrategy, how to export realm users. Available options are: DIFFERENT_FILES, it&#8217;s the default option for this attribute, we will get a file for realm config and multiple files for users (depending on how many users we have and the number of users per one file (50 by default)); SKIP, won&#8217;t export users; REALM_FILE, export users to the same file as realm configuration; SAME_FILE, we will get one file for realm configuration and one for all users (keep-growing-realm.json and keep-growing-users.json). Dkeycloak.migration.file, the file where we want to save data. Remember to use the exact same value as you used for the volume mapping. Run the export command We&#8217;re going to execute the /opt/jboss/keycloak/bin/standalone.sh script included in the jboss/keycloak image to initiate the export process: To clarify the following examples, my example keycloak service runs in the keycloakspringboot_keycloak_1 container. Export to a single file When a realm doesn&#8217;t contain a lot of users it might be appropriate to export it into a single file. The actual command that I&#8217;m going to execute looks like in the snippet below: If the command encounters no problems, you&#8217;ll see console output similar to this: As a result, a new file appears in the keycloak/realms/export directory on my machine: You can quit the process with&#160;Ctr+C. If you want to import that realm, the Keycloak in Docker #2 – How to import a Keycloak realm article describes in detail importing a realm from a file. Export to a directory Keycloak recommends exporting data into a directory if your realm contains more than 500 users: Exporting many users into a directory performs optimally as the directory provider uses a separate transaction for each &#8220;page&#8221; (a file of users). https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide In this case, my command would look like this (notice changes in lines 4 and 6): If the command encounters no problems, you&#8217;ll see console output similar to this: As a result, a group of new files appear in the keycloak/realms/export directory on my machine: You can quit the process with&#160;Ctr+C. If you want to import that realm, see the Keycloak in Docker #6 –&#160;How to import realms from a directory article as it describes in detail importing realms exported to a folder. Export on a container startup Additionally, we can configure our docker-compose.yml file to initiate the export when we start the container (by adding the command config). It can be useful when our docker image doesn&#8217;t provide an equivalent to the standalone.sh script or we just don&#8217;t want to use it. The modified compose file for a single file export looks like this: We&#8217;ll see in logs that the container starts with the provided options: The [&#8230;]</p>
<p>The post <a href="https://keepgrowing.in/tools/keycloak-in-docker-5-how-to-export-a-realm-with-users-and-secrets/">Keycloak in Docker #5 – How to export a realm with users and secrets</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Running a Keycloak service in a Docker container allows us to share its configuration across multiple environments. However, we can also export an entire Keycloak realm in case we need any backups or data transfer between servers.</p>



<span id="more-8800"></span>



<h2 class="wp-block-heading" id="prerequisites">Prerequisites</h2>



<ul class="wp-block-list"><li><a href="https://docs.docker.com/engine/" target="_blank" rel="noreferrer noopener">Docker Engine</a> and <a href="https://docs.docker.com/compose/install/" target="_blank" rel="noreferrer noopener">Docker Compose</a> installed on your machine.</li><li>If this is your first attempt to run Keycloak in Docker, I recommend reading the post <a href="https://keepgrowing.in/tools/keycloak-in-docker-1-how-to-run-keycloak-in-a-docker-container/" target="_blank" rel="noreferrer noopener">Keycloak in Docker # 1 &#8211; How to run Keycloak in a Docker container</a> as I explained the basic configuration there.</li></ul>



<p class="wp-block-paragraph">For reference, below you&#8217;ll find the resulting directory tree for this example:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="348" height="184" src="https://keepgrowing.in/wp-content/uploads/2022/02/directory-tree.webp" alt="directory tree for Keycloak volumes with exported realm" class="wp-image-8911" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/directory-tree.webp 348w, https://keepgrowing.in/wp-content/uploads/2022/02/directory-tree-300x159.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/directory-tree-250x132.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/directory-tree-100x53.webp 100w" sizes="auto, (max-width: 348px) 100vw, 348px" /></figure></div>



<p class="wp-block-paragraph">In short, my goal is to get the <code>export</code> directory containing realm resources (in this case, the <code>keep-growing-realm.json</code> file). Thanks to this, I&#8217;ll be able to backup or recreate a complete realm whenever I need to.</p>



<h2 class="wp-block-heading" id="why-not-export-with-keycloak-admin-console">Why not export with Keycloak Admin console?</h2>



<p class="wp-block-paragraph">The <a href="https://www.keycloak.org/docs/16.1/server_admin/#using-the-admin-console">Keycloak Admin Console</a> provides an easy way to export a realm. However, as you can see in the screenshot below, not all resources can be exported with this method:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="692" height="681" src="https://keepgrowing.in/wp-content/uploads/2021/08/realm-export.webp" alt="Keycloak realm export through Admin Console" class="wp-image-7860" srcset="https://keepgrowing.in/wp-content/uploads/2021/08/realm-export.webp 692w, https://keepgrowing.in/wp-content/uploads/2021/08/realm-export-300x295.webp 300w, https://keepgrowing.in/wp-content/uploads/2021/08/realm-export-520x512.webp 520w, https://keepgrowing.in/wp-content/uploads/2021/08/realm-export-360x354.webp 360w, https://keepgrowing.in/wp-content/uploads/2021/08/realm-export-250x246.webp 250w, https://keepgrowing.in/wp-content/uploads/2021/08/realm-export-100x98.webp 100w" sizes="auto, (max-width: 692px) 100vw, 692px" /></figure></div>



<p class="wp-block-paragraph">The <code>realm-export.json</code> file produced with this technique won&#8217;t contain user data. In addition, client secrets will be masked. Although this approach might be appropriate in some use cases, we won&#8217;t be able to recreate the same instance using only this file.</p>



<p class="wp-block-paragraph">If we want to <a href="https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide" target="_blank" rel="noreferrer noopener">get realm data suitable for backups or cross server migration</a>, we need to run a boot-time export.</p>



<h2 class="wp-block-heading" id="my-example-keycloak-realm">My example Keycloak realm</h2>



<p class="wp-block-paragraph">I have my <code>keep-growing</code> <a href="https://www.keycloak.org/docs/16.1/authorization_services/#_getting_started_hello_world_create_realm" target="_blank" rel="noreferrer noopener">realm with the following users</a>:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="829" height="292" src="https://keepgrowing.in/wp-content/uploads/2022/01/user-list.webp" alt="realm users that will be exported" class="wp-image-8824" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/user-list.webp 829w, https://keepgrowing.in/wp-content/uploads/2022/01/user-list-300x106.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/user-list-768x271.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/01/user-list-700x247.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/01/user-list-520x183.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/01/user-list-360x127.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/01/user-list-250x88.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/user-list-100x35.webp 100w" sizes="auto, (max-width: 829px) 100vw, 829px" /></figure></div>



<p class="wp-block-paragraph">Furthermore, the realm contains the <code>spring-boot-example-app</code> <a href="https://www.keycloak.org/docs/16.1/authorization_services/#_getting_started_hello_world_enabling_authz_services" target="_blank" rel="noreferrer noopener">client</a>. It has the <a href="https://www.keycloak.org/docs/16.1/securing_apps/#_client_authentication_adapter" target="_blank" rel="noreferrer noopener">confidential</a> access type and a secret, as you can see in the screenshot below:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1307" height="429" src="https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret.webp" alt="client secret that will be exported" class="wp-image-8822" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret.webp 1307w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-300x98.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-1024x336.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-768x252.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-700x230.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-520x171.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-360x118.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-250x82.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/genereate-client-secret-100x33.webp 100w" sizes="auto, (max-width: 1307px) 100vw, 1307px" /></figure></div>



<p class="wp-block-paragraph">At the end of this article, I will verify that the users and the secret are properly exported.</p>



<h2 class="wp-block-heading" id="how-to-export-all-resources-from-a-keycloak-realm">How to export all resources from a Keycloak realm</h2>



<p class="wp-block-paragraph">I&#8217;m going to use a <a href="https://docs.docker.com/storage/volumes/" target="_blank" rel="noreferrer noopener">volume</a> to map exported data between the container and my machine. Next, I will show you how to export the data with a command or automatically when running the container. Finally, I&#8217;m going to verify if the export was successful.</p>



<h3 class="wp-block-heading" id="add-a-volume-for-exported-resources">Add a volume for exported resources</h3>



<p class="wp-block-paragraph">First, we need to start our container with a volume that will hold exported data. Therefore, I&#8217;m going to map the <code>./keycloak/realms/export</code> folder on my machine to the <code>/tmp/export</code> directory in the keycloak service. Below you&#8217;ll find my <code>docker-compose.yml</code> file:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">version: '3.3'
services:
  keycloak:
    image: jboss/keycloak:${KEYCLOAK_VERSION}
    ports:
      - "8024:8080"
    environment:
      - KEYCLOAK_USER=${KEYCLOAK_USER}
      - KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}
    volumes:
      - ./keycloak/realms/export:/tmp/export</pre></div>



<p class="wp-block-paragraph">I&#8217;m using my <a href="https://docs.docker.com/compose/environment-variables/#the-env-file" target="_blank" rel="noreferrer noopener">default environmental variables</a> defined in the following <code>.env</code> file:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">KEYCLOAK_VERSION=16.1.1
KEYCLOAK_USER=keycloak
KEYCLOAK_PASSWORD=keycloak</pre></div>



<p class="wp-block-paragraph">Now I&#8217;m going to start the service with the <code>docker-compose up -d</code> command. As we can see in the following screenshot, the volume is properly created and mapped:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="790" height="146" src="https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding.webp" alt="volume binding for exported Keycloak realm" class="wp-image-8833" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding.webp 790w, https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding-300x55.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding-768x142.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding-700x129.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding-520x96.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding-360x67.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding-250x46.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/volume-binding-100x18.webp 100w" sizes="auto, (max-width: 790px) 100vw, 790px" /></figure></div>



<p class="wp-block-paragraph">Obviously, the <code>/tmp/export</code> directory inside the dockerized Keycloak instance is empty as we still need to export our realm:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="675" height="267" src="https://keepgrowing.in/wp-content/uploads/2022/01/empty-tmp-export-in-container.webp" alt="empty export directory in the docker container" class="wp-image-8834" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/empty-tmp-export-in-container.webp 675w, https://keepgrowing.in/wp-content/uploads/2022/01/empty-tmp-export-in-container-300x119.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/empty-tmp-export-in-container-520x206.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/01/empty-tmp-export-in-container-360x142.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/01/empty-tmp-export-in-container-250x99.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/empty-tmp-export-in-container-100x40.webp 100w" sizes="auto, (max-width: 675px) 100vw, 675px" /></figure></div>



<h3 class="wp-block-heading" id="keycloak-export-options-explained">Keycloak export options explained</h3>



<p class="wp-block-paragraph">Let me introduce the properties that we&#8217;re going to use:</p>



<ul class="wp-block-list"><li><code>Djboss.socket.binding.port-offset</code>, we want to run the export on a different port than Keycloak itself. By default, the jboss server in my <code>kecyloak</code> instance uses the <code>9990</code> port. Therefore, providing e.g. 100 as a value here will result in the command using the <code>10090</code> port.</li><li><code>Dkeycloak.migration.action</code>, we specify what we want to do. Available options:<ul><li><code>export</code>,</li><li><code>import</code>.</li></ul></li><li><code>Dkeycloak.migration.provider</code>, we define how we want the data. Available options are:<ul><li><code>singleFile</code>, if we want to export data into a file</li><li><code>dir</code>, if we want to export data into a directory.</li></ul></li><li><code>Dkeycloak.migration.realmName</code>, realm for export. Don&#8217;t specify this parameter if you want to export all realms.</li><li><code>Dkeycloak.migration.usersExportStrategy</code>, how to export realm users. Available options are:<ul><li>DIFFERENT_FILES, it&#8217;s the default option for this attribute, we will get a file for realm config and multiple files for users (depending on how many users we have and the <a href="https://www.keycloak.org/docs/16.1/server_admin/#_keycloak-migration-usersPerFile" target="_blank" rel="noreferrer noopener">number of users per one file</a> (50 by default));</li><li>SKIP, won&#8217;t export users;</li><li>REALM_FILE, export users to the same file as realm configuration;</li><li>SAME_FILE, we will get one file for realm configuration and one for all users (<code>keep-growing-realm.json</code> and <code>keep-growing-users.json</code>).</li></ul></li><li><code>Dkeycloak.migration.file</code>, the file where we want to save data. Remember to use the exact same value as you used for the volume mapping.</li></ul>



<h3 class="wp-block-heading" id="run-the-export-command">Run the export command</h3>



<p class="wp-block-paragraph">We&#8217;re going to execute the <code>/opt/jboss/keycloak/bin/standalone.sh</code> script included in the <a href="https://hub.docker.com/r/jboss/keycloak/" target="_blank" rel="noreferrer noopener">jboss/keycloak</a> image to initiate the export process:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">docker exec -it &lt;CONTAINER NAME&gt; /opt/jboss/keycloak/bin/standalone.sh \
… // required Keycloak export properties</pre></div>



<p class="wp-block-paragraph">To clarify the following examples, my example <code>keycloak</code> service runs in the <code>keycloakspringboot_keycloak_1</code> container.</p>



<h4 class="wp-block-heading" id="export-to-a-single-file">Export to a single file</h4>



<p class="wp-block-paragraph">When a realm doesn&#8217;t contain a lot of users it might be appropriate to export it into a single file. The actual command that I&#8217;m going to execute looks like in the snippet below:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">docker exec -it keycloakspringboot_keycloak_1 /opt/jboss/keycloak/bin/standalone.sh \
-Djboss.socket.binding.port-offset=100 \
-Dkeycloak.migration.action=export \
-Dkeycloak.migration.provider=singleFile \
-Dkeycloak.migration.realmName=keep-growing \
-Dkeycloak.migration.usersExportStrategy=REALM_FILE \
-Dkeycloak.migration.file=/tmp/export/keep-growing-realm.json</pre></div>



<p class="wp-block-paragraph">If the command encounters no problems, you&#8217;ll see console output similar to this:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
12:11:10,399 INFO  [org.keycloak.services] (ServerService Thread Pool -- 60) KC-SERVICES0034: Export of realm 'keep-growing' requested.
12:11:10,400 INFO  [org.keycloak.exportimport.singlefile.SingleFileExportProvider] (ServerService Thread Pool -- 60) Exporting realm 'keep-growing' into file /tmp/export/keep-growing-realm.json
12:11:10,790 INFO  [org.keycloak.services] (ServerService Thread Pool -- 60) KC-SERVICES0035: Export finished successfully
…
12:11:11,195 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:10090/management
12:11:11,196 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:10090</pre></div>



<p class="wp-block-paragraph">As a result, a new file appears in the <code>keycloak/realms/export</code> directory on my machine:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="345" height="113" src="https://keepgrowing.in/wp-content/uploads/2022/01/new-exported-file.webp" alt="exported Keycloak realm in a file" class="wp-image-8854" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/new-exported-file.webp 345w, https://keepgrowing.in/wp-content/uploads/2022/01/new-exported-file-300x98.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/new-exported-file-250x82.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/new-exported-file-100x33.webp 100w" sizes="auto, (max-width: 345px) 100vw, 345px" /></figure></div>



<p class="wp-block-paragraph">You can quit the process with&nbsp;<code>Ctr+C</code>.</p>



<p class="wp-block-paragraph">If you want to import that realm, the <a href="https://keepgrowing.in/tools/keycloak-in-docker-2-how-to-import-a-keycloak-realm/" target="_blank" rel="noreferrer noopener">Keycloak in Docker #2 – How to import a Keycloak realm</a> article describes in detail importing a realm from a file.</p>



<h4 class="wp-block-heading" id="export-to-a-single-file">Export to a directory</h4>



<p class="wp-block-paragraph">Keycloak recommends exporting data into a directory if your realm contains more than 500 users:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Exporting many users into a directory performs optimally as the directory provider uses a separate transaction for each &#8220;page&#8221; (a file of users).</p><cite><a href="https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide" target="_blank" rel="noreferrer noopener">https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide</a></cite></blockquote>



<p class="wp-block-paragraph">In this case, my command would look like this (notice changes in lines 4 and 6):</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">docker exec -it keycloakspringboot_keycloak_1 /opt/jboss/keycloak/bin/standalone.sh \
-Djboss.socket.binding.port-offset=100 \
-Dkeycloak.migration.action=export \
-Dkeycloak.migration.provider=dir \
-Dkeycloak.migration.realmName=keep-growing \
-Dkeycloak.migration.dir=/tmp/export</pre></div>



<p class="wp-block-paragraph">If the command encounters no problems, you&#8217;ll see console output similar to this:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">…
12:29:31,726 INFO  [org.keycloak.services] (ServerService Thread Pool -- 53) KC-SERVICES0034: Export of realm 'keep-growing' requested.
12:29:32,107 INFO  [org.keycloak.exportimport.dir.DirExportProvider] (ServerService Thread Pool -- 53) Realm 'keep-growing' - data exported
12:29:32,212 INFO  [org.keycloak.exportimport.dir.DirExportProvider] (ServerService Thread Pool -- 53) Users 0-3 exported
12:29:32,214 INFO  [org.keycloak.services] (ServerService Thread Pool -- 53) KC-SERVICES0035: Export finished successfully
…</pre></div>



<p class="wp-block-paragraph">As a result, a group of new files appear in the <code>keycloak/realms/export</code> directory on my machine:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="375" height="139" src="https://keepgrowing.in/wp-content/uploads/2022/01/exported-directory.webp" alt="exported Keycloak realm in a directory" class="wp-image-8859" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/exported-directory.webp 375w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-directory-300x111.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-directory-360x133.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-directory-250x93.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-directory-100x37.webp 100w" sizes="auto, (max-width: 375px) 100vw, 375px" /></figure></div>



<p class="wp-block-paragraph">You can quit the process with&nbsp;<code>Ctr+C</code>.</p>



<p class="wp-block-paragraph">If you want to import that realm, see the <a href="https://keepgrowing.in/tools/keycloak-in-docker-6-how-to-import-realms-from-a-directory/" target="_blank" rel="noreferrer noopener">Keycloak in Docker #6 –&nbsp;How to import realms from a directory</a> article as it describes in detail importing realms exported to a folder.</p>



<h3 class="wp-block-heading" id="data-included-in-the-exported-keycloak-realm-resources">Export on a container startup</h3>



<p class="wp-block-paragraph">Additionally, we can configure our <code>docker-compose.yml</code> file to initiate the export when we start the container (by adding the <a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#command" target="_blank" rel="noreferrer noopener">command</a> config). It can be useful when our docker image doesn&#8217;t provide an equivalent to the <code>standalone.sh</code> script or we just don&#8217;t want to use it. The modified compose file for a single file export looks like this:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">version: '3.3'
services:
  keycloak:
    image: jboss/keycloak:${KEYCLOAK_VERSION}
    ports:
      - "8024:8080"
    environment:
      - KEYCLOAK_USER=${KEYCLOAK_USER}
      - KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}
    volumes:
      - ./keycloak/realms/export:/tmp/export
    command:
      - "-Dkeycloak.migration.action=export"
      - "-Dkeycloak.migration.provider=singleFile"
      - "-Dkeycloak.migration.realmName=keep-growing"
      - "-Dkeycloak.migration.usersExportStrategy=REALM_FILE"
      - "-Dkeycloak.migration.file=/tmp/export/keep-growing-realm.json"</pre></div>



<p class="wp-block-paragraph">We&#8217;ll see in logs that the container starts with the provided options:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1572" height="224" src="https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs.webp" alt="exporting Keycloak realm on container startup" class="wp-image-8955" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs.webp 1572w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-300x43.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-1024x146.webp 1024w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-768x109.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-1536x219.webp 1536w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-700x100.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-520x74.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-360x51.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-250x36.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/export-on-startup-logs-100x14.webp 100w" sizes="auto, (max-width: 1572px) 100vw, 1572px" /></figure></div>



<p class="wp-block-paragraph">The export will proceed as in the previously described methods.</p>



<h3 class="wp-block-heading" id="data-included-in-the-exported-keycloak-realm-resources">Data included in the exported Keycloak realm resources</h3>



<p class="wp-block-paragraph">We&#8217;re going to find the secret generated for the <code>spring-boot-example-app</code> client in the realm config file:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="777" height="280" src="https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret.webp" alt="exported client secret" class="wp-image-8861" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret.webp 777w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret-300x108.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret-768x277.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret-700x252.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret-520x187.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret-360x130.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret-250x90.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-secret-100x36.webp 100w" sizes="auto, (max-width: 777px) 100vw, 777px" /></figure></div>



<p class="wp-block-paragraph">Furthermore, the users are included in the exported assets as well. In case of the directory export the users are stored in the <code>keep-growing-users-0.json</code> file. For the single file export, the users are included directly in the <code>keep-growing-realm.json</code> file:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="942" height="425" src="https://keepgrowing.in/wp-content/uploads/2022/01/exported-users.webp" alt="exported users" class="wp-image-8863" srcset="https://keepgrowing.in/wp-content/uploads/2022/01/exported-users.webp 942w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-users-300x135.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-users-768x346.webp 768w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-users-700x316.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-users-520x235.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-users-360x162.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-users-250x113.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/01/exported-users-100x45.webp 100w" sizes="auto, (max-width: 942px) 100vw, 942px" /></figure></div>



<h2 class="wp-block-heading" id="troubleshooting">Troubleshooting</h2>



<p class="wp-block-paragraph">What to check when the export didn&#8217;t work as planned?</p>



<h3 class="wp-block-heading" id="null-pointer-exception">Null pointer exception</h3>



<p class="wp-block-paragraph">If you see the <code>NullPointerException</code> error in the logs make sure that the <code>Dkeycloak.migration.realmName</code> property value is consistent with the actual name of the realm you want to export. The following example error shows what happens if I provide <code>non-existing</code> to the command but my realm&#8217;s id is actually <code>keep-growing</code>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">11:42:20,795 INFO  [org.keycloak.services] (ServerService Thread Pool -- 54) KC-SERVICES0034: Export of realm 'non-existing' requested.
11:42:20,795 INFO  [org.keycloak.exportimport.singlefile.SingleFileExportProvider] (ServerService Thread Pool -- 54) Exporting realm 'non-existing' into file /tmp/export/keep-growing-realm.json
11:42:20,804 FATAL [org.keycloak.services] (ServerService Thread Pool -- 54) Error during startup: java.lang.NullPointerException</pre></div>



<h3 class="wp-block-heading" id="missing-export-files">No such file or directory</h3>



<p class="wp-block-paragraph">If you see the <code>No such file or directory</code> message in the logs make sure that the <code>Dkeycloak.migration.file</code> property value points to a path that actually exists within the container. The following example error shows what happens if I provide <code>/tmp/wrong/directory/path/keep-growing-realm.json</code> to the command but Docker actually created a folder according to the mapped volume which points to <code>/tmp/export</code>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">Exporting realm 'keep-growing' into file /tmp/wrong/directory/path/keep-growing-realm.json
11:50:20,269 FATAL [org.keycloak.services] (ServerService Thread Pool -- 53) Error during startup: java.lang.RuntimeException: Error during export/import: /tmp/wrong/directory/path/keep-growing-realm.json (No such file or directory)</pre></div>



<p class="wp-block-paragraph">Verify that you actually restarted the container after adding the volume config to the <code>docker-compose.yml</code> file. Otherwise, the mapped directory won&#8217;t be created for you.</p>



<h3 class="wp-block-heading" id="missing-export-files">Missing export files</h3>



<p class="wp-block-paragraph">There are no errors in logs but you can&#8217;t find the exported files on your machine? Verify that the <code>Dkeycloak.migration.file</code> property value is consistent with the volume mapping. The following example shows what happens if I provide <code>/tmp/keep-growing-realm-test.json</code> instead of <code>/tmp/export/keep-growing-realm-test.json</code>:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="751" height="345" src="https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path.webp" alt="realm exported to a wrong path" class="wp-image-8900" srcset="https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path.webp 751w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path-300x138.webp 300w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path-700x322.webp 700w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path-520x239.webp 520w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path-360x165.webp 360w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path-250x115.webp 250w, https://keepgrowing.in/wp-content/uploads/2022/02/realm-export-to-wrong-path-100x46.webp 100w" sizes="auto, (max-width: 751px) 100vw, 751px" /></figure></div>



<p class="wp-block-paragraph">You can always verify the location of the exported data in the command logs:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">11:59:32,192 INFO  [org.keycloak.services] (ServerService Thread Pool -- 53) KC-SERVICES0034: Export of realm 'keep-growing' requested.
11:59:32,192 INFO  [org.keycloak.exportimport.singlefile.SingleFileExportProvider] (ServerService Thread Pool -- 53) Exporting realm 'keep-growing' into file /tmp/keep-growing-realm-test.json
11:59:32,805 INFO  [org.keycloak.services] (ServerService Thread Pool -- 53) KC-SERVICES0035: Export finished successfully</pre></div>



<h2 class="wp-block-heading" id="read-more-on-exporting-keycloak-realm">Read more on exporting Keycloak realm</h2>



<ul class="wp-block-list"><li>The Jboss image documentation on <a href="https://hub.docker.com/r/jboss/keycloak/" target="_blank" rel="noreferrer noopener">exporting a realm</a></li><li>The Keycloak documentation on i<a href="https://www.keycloak.org/docs/16.1/server_admin/#assembly-exporting-importing_server_administration_guide" target="_blank" rel="noreferrer noopener">mporting and exporting the database</a></li></ul>



<p class="has-text-align-center has-small-font-size wp-block-paragraph">Photo by&nbsp;<a href="https://www.pexels.com/@rodnae-prod?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">RODNAE Productions</a>&nbsp;from&nbsp;<a href="https://www.pexels.com/photo/couple-friends-glass-warehouse-7464426/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noreferrer noopener">Pexels</a></p>
<p>The post <a href="https://keepgrowing.in/tools/keycloak-in-docker-5-how-to-export-a-realm-with-users-and-secrets/">Keycloak in Docker #5 – How to export a realm with users and secrets</a> appeared first on <a href="https://keepgrowing.in">keep_growing</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://keepgrowing.in/tools/keycloak-in-docker-5-how-to-export-a-realm-with-users-and-secrets/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8800</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)
Minified using Disk

Served from: keepgrowing.in @ 2026-09-22 15:53:10 by W3 Total Cache
-->