{"id":68243,"date":"2020-09-04T15:54:57","date_gmt":"2020-09-04T15:54:57","guid":{"rendered":"https:\/\/www.baeldung.com\/?p=86616"},"modified":"2020-09-04T15:54:57","modified_gmt":"2020-09-04T15:54:57","slug":"custom-user-attributes-with-keycloak","status":"publish","type":"post","link":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/2020\/09\/04\/custom-user-attributes-with-keycloak\/","title":{"rendered":"Custom User Attributes with Keycloak"},"content":{"rendered":"<p class=\"syndicated-attribution\"><meta name= \\\"keywords \\\" content= \\\"\u96fb\u5b50\u8a08\u7b97\u6a5f, \u6559\u80b2, IT \u96fb\u8166\u73ed,\u96fb\u8166\u88dc\u7fd2\uff0c \u96fb\u8166\u73ed\uff0c \u5bb6\u6559\uff0c \u79c1\u4eba\u8001\u5e2b\uff0c \u8cc7\u8a0a\u6280\u8853\uff0c \u7a0b\u5e8f\u8a2d\u8a08\uff0c \u96fb\u5b50\u8a08\u7b97\u6a5f\uff0c \u904a\u6232\uff0c \u860b\u679c\uff0c \u96fb\u5f71\uff0c \u8a08\u7b97\u6a5f\uff0c\u7de8\u78bc\uff0c Java\uff0c C\/C++\uff0c JavaScript\uff0c PHP\uff0c HTML\uff0c CSS\uff0c MySQL\uff0c mobile\uff0c Android\uff0c \u52d5\u6f2b\uff0c Python\uff0c teacher\uff0c \u88dc\u7fd2\uff0c \u96fb\u8166\u88dc\u7fd2 \u8cc7\u8a0a, \u7535\u5b50\u8ba1\u7b97\u673a, IT ,Game, apple, movie, Computer,student,Java,\u6559\u80b2, ,\u5b66\u751f, \u5b66\u4e60, learn, \u6559\u5b66,  Android, apple,anime, animation, \u4fe1\u606f\u6280\u672f, \u7a0b\u5e8f\u8bbe\u8ba1, \u79fb\u52a8\u7535\u8bdd, \u8cc7\u8a0a\u79d1\u6280,Game, Jeu, Juego,Call Of Duty ,\u4f7f\u547d\u53ec\u559a , \u6e38\u620f, \u7535\u5b50\u6e38\u620f,, \u591a\u4eba\u7535\u5b50\u6e38\u620f, \u7f51\u7edc\u6e38\u620f\uff0conline\uff0conline game, \u624b\u673a\u6e38\u620f, mobile \\\"><\/p>\n<h2  data-id=\"overview\">1. Overview<\/h2>\n<div class=\"bd-anchor\" id=\"overview\"><\/div>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.keycloak.org\/\">Keycloak<\/a> is a third-party authorization server that manages users of our web or mobile applications.<\/p>\n<p>It offers some default attributes, such as first name, last name, and email to be stored for any given user. But many times, these are not enough, and we might need to add some extra user attributes specific to our application.<\/p>\n<p>In this tutorial, we&#8217;ll see <strong>how we can add custom user attributes to our Keycloak authorization server and access them in a Spring-based backend<\/strong>.<\/p>\n<p>First, we&#8217;ll see this for a <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-boot-keycloak\">standalone<\/a> Keycloak server, and then for an <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/keycloak-embedded-in-spring-boot-app\">embedded<\/a> one.<\/p>\n<h2  data-id=\"standalone\">2. Standalone Server<\/h2>\n<div class=\"bd-anchor\" id=\"standalone\"><\/div>\n<h3  data-id=\"add-attrs\">2.1. Adding Custom User Attributes<\/h3>\n<div class=\"bd-anchor\" id=\"add-attrs\"><\/div>\n<p>The first step here is to go to Keycloak&#8217;s admin console. For that, we&#8217;ll need to start the server by running this command from our Keycloak distribution&#8217;s <em>bin<\/em> folder:<\/p>\n<pre><code class=\"language-bash\">.\/standalone.sh -Djboss.socket.binding.port-offset=100<\/code><\/pre>\n<p>Then we need to go to the <a href=\"http:\/\/localhost:8180\/auth\/admin\">admin console<\/a> and key-in the <em>initial1<\/em>\/<em>zaq1!QAZ <\/em>credentials.<\/p>\n<p>Next, we&#8217;ll click on <em>Users<\/em> under the <em>Manage<\/em> tab and then <em>View all users<\/em>:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1.png\"><img decoding=\"async\" loading=\"lazy\" width=\"2048\" height=\"902\" class=\"aligncenter size-full wp-image-86621\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1.png\" alt=\"\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1.png 2048w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1-300x132.png 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1-1024x451.png 1024w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1-768x338.png 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1-1536x677.png 1536w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/ViewAllUsers-2048x902-1-100x44.png 100w\" sizes=\"(max-width: 2048px) 100vw, 2048px\" \/><\/a><\/p>\n<p>Here we can see the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-boot-keycloak#create-userrole\">user we&#8217;d added previously<\/a>:\u00a0<em>user1<\/em>.<\/p>\n<p>Now let&#8217;s click on its <em>ID<\/em> and go to the <em>Attributes<\/em> tab to add a new one, <em>DOB<\/em> for date of birth:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1.png\"><img decoding=\"async\" loading=\"lazy\" width=\"2048\" height=\"519\" class=\"aligncenter size-full wp-image-86620\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1.png\" alt=\"\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1.png 2048w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1-300x76.png 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1-1024x260.png 1024w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1-768x195.png 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1-1536x389.png 1536w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/AddDOB-2048x519-1-100x25.png 100w\" sizes=\"(max-width: 2048px) 100vw, 2048px\" \/><\/a><\/p>\n<p>After clicking <em>Save<\/em>, the custom attribute gets added to the user&#8217;s information.<\/p>\n<p>Next, we need to add a mapping for this attribute as a custom claim so that it&#8217;s available in the JSON payload for the user&#8217;s token.<\/p>\n<p>For that, we need to go to our application&#8217;s client on the admin console. Recall that earlier we&#8217;d created a client, <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-boot-keycloak#create-client\"><em>login-app<\/em><\/a>:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1.png\"><img decoding=\"async\" loading=\"lazy\" width=\"2048\" height=\"521\" class=\"aligncenter size-full wp-image-86619\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1.png\" alt=\"\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1.png 2048w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1-300x76.png 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1-1024x261.png 1024w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1-768x195.png 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1-1536x391.png 1536w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/client_LoginApp-2048x521-1-100x25.png 100w\" sizes=\"(max-width: 2048px) 100vw, 2048px\" \/><\/a><\/p>\n<p>Now, let&#8217;s click on it and go to its <em>Mappers<\/em> tab to create a new mapping:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-86618\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper.png\" alt=\"\" width=\"774\" height=\"601\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper.png 1624w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper-300x233.png 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper-1024x796.png 1024w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper-768x597.png 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper-1536x1194.png 1536w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/mapper-100x78.png 100w\" sizes=\"(max-width: 774px) 100vw, 774px\" \/><\/a><\/p>\n<p>First, we&#8217;ll select the <em>Mapper Type<\/em> as <em>User Attribute<\/em> and then set <em>Name<\/em>, <em>User Attribute<\/em>, and <em>Token Claim Name<\/em> as <em>DOB<\/em>. <em>Claim JSON Type<\/em> should be set as <em>String<\/em>.<\/p>\n<p>On clicking <em>Save<\/em>, our mapping is ready. So now, we&#8217;re equipped from the Keycloak end to receive <em>DOB<\/em> as a custom user attribute.<\/p>\n<p>In the next section, <strong>we&#8217;ll see how to access it via an API call<\/strong>.<\/p>\n<h3  data-id=\"access-attrs\">2.2. Accessing Custom User Attributes<\/h3>\n<div class=\"bd-anchor\" id=\"access-attrs\"><\/div>\n<p>Building on top of our <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-boot-keycloak#springboot\">Spring Boot application<\/a>, let&#8217;s add a new REST controller to get the user attribute we added:<\/p>\n<pre><code class=\"language-java\">@Controller\r\npublic class CustomUserAttrController {\r\n    @GetMapping(path = \"\/users\")\r\n    public String getUserInfo(Model model) {\r\n        KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) \r\n          SecurityContextHolder.getContext().getAuthentication();\r\n        \r\n        Principal principal = (Principal) authentication.getPrincipal();        \r\n        String dob=\"\";\r\n        \r\n        if (principal instanceof KeycloakPrincipal) {\r\n            KeycloakPrincipal kPrincipal = (KeycloakPrincipal) principal;\r\n            IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();\r\n            Map&lt;String, Object&gt; customClaims = token.getOtherClaims();\r\n            if (customClaims.containsKey(\"DOB\")) {\r\n                dob = String.valueOf(customClaims.get(\"DOB\"));\r\n            }\r\n        }\r\n        \r\n        model.addAttribute(\"username\", principal.getName());\r\n        model.addAttribute(\"dob\", dob);\r\n        return \"userInfo\";\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>As we can see, here we first obtained the <em>KeycloakAuthenticationToken<\/em> from the security context and then extracted the <em>Principal<\/em> from it. After casting it as a <em>KeycloakPrincipal<\/em>, we obtained its <em>IDToken<\/em>.<\/p>\n<p><em>DOB<\/em> can then be extracted from this <em>IDToken<\/em>&#8216;s <em>OtherClaims<\/em>.<\/p>\n<p>Here&#8217;s the template, named\u00a0<em>userInfo.html,<\/em> that we&#8217;ll use to display this information:<\/p>\n<pre><code class=\"language-html\">&lt;div id=\"container\"&gt;\r\n    &lt;h1&gt;Hello, &lt;span th:text=\"${username}\"&gt;--name--&lt;\/span&gt;.&lt;\/h1&gt;\r\n    &lt;h3&gt;Your Date of Birth as per our records is &lt;span th:text=\"${dob}\"\/&gt;.&lt;\/h3&gt;\r\n&lt;\/div&gt;<\/code><\/pre>\n<h3  data-id=\"testing\">2.3. Testing<\/h3>\n<div class=\"bd-anchor\" id=\"testing\"><\/div>\n<p>On starting the Boot application, we should navigate to <em><a href=\"http:\/\/localhost:8081\/users\">http:\/\/localhost:8081\/users<\/a>. <\/em>We&#8217;ll first be asked to enter credentials.<\/p>\n<p>After entering <em>user1<\/em>&#8216;s credentials, we should see this page:<\/p>\n<p><a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/DOB.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-86617\" src=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/DOB.png\" alt=\"\" width=\"713\" height=\"198\" srcset=\"https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/DOB.png 1290w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/DOB-300x83.png 300w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/DOB-1024x284.png 1024w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/DOB-768x213.png 768w, https:\/\/www.baeldung.com\/wp-content\/uploads\/2020\/09\/DOB-100x28.png 100w\" sizes=\"(max-width: 713px) 100vw, 713px\" \/><\/a><\/p>\n<h2  data-id=\"embedded\">3. Embedded Server<\/h2>\n<div class=\"bd-anchor\" id=\"embedded\"><\/div>\n<p>Now let&#8217;s see how to achieve the same thing on an embedded Keycloak instance.<\/p>\n<h3  data-id=\"add-attrs-1\">3.1. Adding Custom User Attributes<\/h3>\n<div class=\"bd-anchor\" id=\"add-attrs-1\"><\/div>\n<p>Basically, we need to do the same steps here, only that <strong>we&#8217;ll need to save them as <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/keycloak-embedded-in-spring-boot-app#keycloak-config\">pre-configurations<\/a> in our realm definition file, <em>baeldung-realm.json<\/em><\/strong>.<\/p>\n<p>To add the attribute <em>DOB<\/em> to our user <em>john@test.com<\/em>, first, we need to configure its attributes:<\/p>\n<pre><code class=\"language-json\">\"attributes\" : {\r\n    \"DOB\" : \"1984-07-01\"\r\n},<\/code><\/pre>\n<p>Then add the protocol mapper for <em>DOB<\/em>:<\/p>\n<pre><code class=\"language-json\">\"protocolMappers\": [\r\n    {\r\n    \"id\": \"c5237a00-d3ea-4e87-9caf-5146b02d1a15\",\r\n    \"name\": \"DOB\",\r\n    \"protocol\": \"openid-connect\",\r\n    \"protocolMapper\": \"oidc-usermodel-attribute-mapper\",\r\n    \"consentRequired\": false,\r\n    \"config\": {\r\n        \"userinfo.token.claim\": \"true\",\r\n        \"user.attribute\": \"DOB\",\r\n        \"id.token.claim\": \"true\",\r\n        \"access.token.claim\": \"true\",\r\n        \"claim.name\": \"DOB\",\r\n        \"jsonType.label\": \"String\"\r\n        }\r\n    }\r\n]<\/code><\/pre>\n<p>That&#8217;s all we need here.<\/p>\n<p>Now that we&#8217;ve seen the authorization server part of adding a custom user attribute, it&#8217;s time to look at how the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/spring-security-oauth-resource-server\">resource server<\/a> can access the user&#8217;s <em>DOB<\/em>.<\/p>\n<h3  data-id=\"access-attrs-1\">3.2. Accessing Custom User Attributes<\/h3>\n<div class=\"bd-anchor\" id=\"access-attrs-1\"><\/div>\n<p>On the resource server-side, the custom attributes will simply be available to us as claim values in the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/docs.spring.io\/spring-security\/site\/docs\/current\/api\/org\/springframework\/security\/core\/annotation\/AuthenticationPrincipal.html\"><em>AuthenticationPrincipal<\/em><\/a>.<\/p>\n<p>Let&#8217;s code an API for it:<\/p>\n<pre><code class=\"language-java\">@RestController\r\npublic class CustomUserAttrController {\r\n    @GetMapping(\"\/user\/info\/custom\")\r\n    public Map&lt;String, Object&gt; getUserInfo(@AuthenticationPrincipal Jwt principal) {\r\n        return Collections.singletonMap(\"DOB\", principal.getClaimAsString(\"DOB\"));\r\n    }\r\n}<\/code><\/pre>\n<h3  data-id=\"testing-1\">3.3. Testing<\/h3>\n<div class=\"bd-anchor\" id=\"testing-1\"><\/div>\n<p>Now let&#8217;s test it using JUnit.<\/p>\n<p>We&#8217;ll first need to obtain an access token and then call the <em>\/user\/info\/custom<\/em> API endpoint on the resource server:<\/p>\n<pre><code class=\"language-java\">@Test\r\npublic void givenUserWithReadScope_whenGetUserInformationResource_thenSuccess() {\r\n    String accessToken = obtainAccessToken(\"read\");\r\n    Response response = RestAssured.given()\r\n      .header(HttpHeaders.AUTHORIZATION, \"Bearer \" + accessToken)\r\n      .get(userInfoResourceUrl);\r\n    assertThat(response.as(Map.class)).containsEntry(\"DOB\", \"1984-07-01\");\r\n}<\/code><\/pre>\n<p>As we can see, here we verified that <strong>we&#8217;re getting the same <em>DOB<\/em> value as we added in the user&#8217;s attributes<\/strong>.<\/p>\n<h2  data-id=\"conclusion\">4. Conclusion<\/h2>\n<div class=\"bd-anchor\" id=\"conclusion\"><\/div>\n<p>In this tutorial, <strong>we learned how to add extra attributes to a user in Keycloak.<br \/>\n<br \/>\n<\/strong><\/p>\n<p>We saw this for both a standalone and an embedded instance. We also saw how to access these custom claims in a REST API on the backend in both scenarios.<\/p>\n<p>As always, the source code is available over on GitHub. For the standalone server, it&#8217;s on the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/github.com\/eugenp\/tutorials\/tree\/master\/spring-boot-modules\/spring-boot-keycloak\">tutorials GitHub<\/a>, and for the embedded instance, on the <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/github.com\/Baeldung\/spring-security-oauth\/tree\/master\/oauth-jwt\">OAuth GitHub<\/a>.<\/p>\n<p>The post <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/keycloak-custom-user-attributes\/\" >Custom User Attributes with Keycloak<\/a> first appeared on <a href=\"https:\/\/feeds.feedblitz.com\/~\/t\/0\/0\/baeldung\/~https:\/\/www.baeldung.com\/\" >Baeldung<\/a>.<\/p>\n<p><Img align=\"left\" border=\"0\" height=\"1\" width=\"1\" alt=\"\" style=\"border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;\" hspace=\"0\" src=\"https:\/\/feeds.feedblitz.com\/~\/i\/635065308\/0\/baeldung\"><\/p>\n<div style=\"clear:both;padding-top:0.2em;\"><a title=\"Like on Facebook\" href=\"https:\/\/feeds.feedblitz.com\/_\/28\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/fblike20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Share on Google+\" href=\"https:\/\/feeds.feedblitz.com\/_\/30\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/googleplus20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Pin it!\" href=\"https:\/\/feeds.feedblitz.com\/_\/29\/635065308\/baeldung,https%3A%2F%2Fwww.baeldung.com%2Fwp-content%2Fuploads%2F2020%2F09%2FViewAllUsers-2048x902-1.png\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/pinterest20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Tweet This\" href=\"https:\/\/feeds.feedblitz.com\/_\/24\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/twitter20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Subscribe by email\" href=\"https:\/\/feeds.feedblitz.com\/_\/19\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/email20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a title=\"Subscribe by RSS\" href=\"https:\/\/feeds.feedblitz.com\/_\/20\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/rss20.png\" style=\"border:0;margin:0;padding:0;\"><\/a>&#160;<a rel=\"NOFOLLOW\" title=\"View Comments\" href=\"https:\/\/www.baeldung.com\/keycloak-custom-user-attributes#respond\"><img decoding=\"async\" height=\"20\" style=\"border:0;margin:0;padding:0;\" src=\"https:\/\/assets.feedblitz.com\/i\/comments20.png\"><\/a>&#160;<a title=\"Follow Comments via RSS\" href=\"https:\/\/www.baeldung.com\/keycloak-custom-user-attributes\/feed\/\"><img decoding=\"async\" height=\"20\" style=\"border:0;margin:0;padding:0;\" src=\"https:\/\/assets.feedblitz.com\/i\/commentsrss20.png\"><\/a>&#160;<\/div>\n\n<p class=\"syndicated-attribution\"><figure class= \\\"wp-block-image alignnone \\\"><img src= \\\"http:\/\/itteacheritfreelance.hk\/test\/wordpress\/wp-content\/uploads\/2016\/05\/logo2-2.png\\\" alt=\\\"IT\u96fb\u8166\u88dc\u7fd2 java\u88dc\u7fd2 \u70ba\u5927\u5bb6\u914d\u5c0d\u96fb\u8166\u88dc\u7fd2,IT freelance, \u79c1\u4eba\u8001\u5e2b, PHP\u88dc\u7fd2,CSS\u88dc\u7fd2,XML,Java\u88dc\u7fd2,MySQL\u88dc\u7fd2,graphic design\u88dc\u7fd2,\u4e2d\u5c0f\u5b78ICT\u88dc\u7fd2,\u4e00\u5c0d\u4e00\u79c1\u4eba\u88dc\u7fd2\u548cFreelance\u81ea\u7531\u5de5\u4f5c\u914d\u5c0d\u3002\\\"\/><figcaption>\u7acb\u523b\u8a3b\u518a\u53ca\u5831\u540d\u96fb\u8166\u88dc\u7fd2\u8ab2\u7a0b\u5427!<\/figcaption><\/figure>\r\n<\/br>Find A Teacher Form:\r\n<\/br>https:\/\/docs.google.com\/forms\/d\/1vREBnX5n262umf4wU5U2pyTwvk9O-JrAgblA-wH9GFQ\/viewform?edit_requested=true#responses\r\n<\/br><\/br>Email:\r\n<\/br>public1989two@gmail.com<br><br><br><br><br><br><br>\r\n<a href=www.itsec.hk style=color:#FFFFFF;>www.itsec.hk<\/a><br>\r\n<a href=\\\"www.itsec.vip\\\" style=color:#FFFFFF;>www.itsec.vip<\/a><br>\r\n<a href=\\\"www.itseceu.uk\\\" style=color:#FFFFFF;>www.itseceu.uk<\/a><br><\/p>","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>Learn how to add extra attributes to a user in Keycloak.<\/p>\n<p>The post <a rel=\"NOFOLLOW noopener noreferrer\" href=\"https:\/\/feeds.feedblitz.com\/~\/635065308\/0\/baeldung~Custom-User-Attributes-with-Keycloak\/\" target=\"_blank\">Custom User Attributes with Keycloak<\/a> first appeared on <a rel=\"NOFOLLOW noopener noreferrer\" href=\"https:\/\/www.baeldung.com\/\" target=\"_blank\">Baeldung<\/a>.<\/p>\n<div><a title=\"Like on Facebook\" href=\"https:\/\/feeds.feedblitz.com\/_\/28\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/fblike20.png\"><\/a>&nbsp;<a title=\"Share on Google+\" href=\"https:\/\/feeds.feedblitz.com\/_\/30\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/googleplus20.png\"><\/a>&nbsp;<a title=\"Pin it!\" href=\"https:\/\/feeds.feedblitz.com\/_\/29\/635065308\/baeldung,https%3A%2F%2Fwww.baeldung.com%2Fwp-content%2Fuploads%2F2020%2F09%2FViewAllUsers-2048x902-1.png\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/pinterest20.png\"><\/a>&nbsp;<a title=\"Tweet This\" href=\"https:\/\/feeds.feedblitz.com\/_\/24\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/twitter20.png\"><\/a>&nbsp;<a title=\"Subscribe by email\" href=\"https:\/\/feeds.feedblitz.com\/_\/19\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/email20.png\"><\/a>&nbsp;<a title=\"Subscribe by RSS\" href=\"https:\/\/feeds.feedblitz.com\/_\/20\/635065308\/baeldung\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/rss20.png\"><\/a>&nbsp;<a rel=\"NOFOLLOW\" title=\"View Comments\" href=\"https:\/\/www.baeldung.com\/keycloak-custom-user-attributes#respond\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/comments20.png\"><\/a>&nbsp;<a title=\"Follow Comments via RSS\" href=\"https:\/\/www.baeldung.com\/keycloak-custom-user-attributes\/feed\/\"><img decoding=\"async\" height=\"20\" src=\"https:\/\/assets.feedblitz.com\/i\/commentsrss20.png\"><\/a>&nbsp;<\/div>\n<\/div>","protected":false},"author":770,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"slim_seo":{"title":"Custom User Attributes with Keycloak - ITTeacherITFreelance.hk","description":"Learn how to add extra attributes to a user in Keycloak. The post Custom User Attributes with Keycloak first appeared on Baeldung . &nbsp; &nbsp; &nbsp; &nbsp;"},"footnotes":""},"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/68243"}],"collection":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/770"}],"replies":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=68243"}],"version-history":[{"count":9,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/68243\/revisions"}],"predecessor-version":[{"id":72479,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/68243\/revisions\/72479"}],"wp:attachment":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=68243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=68243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=68243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}