{"id":1563,"date":"2022-09-30T09:40:06","date_gmt":"2022-09-29T20:40:06","guid":{"rendered":"https:\/\/www.ronella.xyz\/?p=1563"},"modified":"2024-04-11T14:24:36","modified_gmt":"2024-04-11T02:24:36","slug":"keycloak-jwt-generation-password-grant-type","status":"publish","type":"post","link":"https:\/\/www.ronella.xyz\/?p=1563","title":{"rendered":"Keycloak &#8211; JWT Generation &#8211; Password Grant Type"},"content":{"rendered":"<h2>Pre-requisite<\/h2>\n<ul>\n<li>Keycloak 19<a href=\"https:\/\/www.keycloak.org\/archive\/downloads-19.0.2.html\">^1<\/a><\/li>\n<\/ul>\n<h2>Creating a New Client and User<\/h2>\n<ol>\n<li>\n<p><strong>Sign in<\/strong> to <strong>keycloak admin console<\/strong> using the following address:<\/p>\n<blockquote>\n<p>Must know a valid credential. <\/p>\n<\/blockquote>\n<p><a href=\"http:\/\/localhost:8080\/admin\/\">http:\/\/localhost:8080\/admin\/<\/a><\/p>\n<\/li>\n<li>\n<p><strong>Switch or create a realm<\/strong> that is <strong>NOT a master realm<\/strong> <em>(i.e. leave the master realms for keycloak usage only)<\/em>, like the following <em>(i.e. jwtrealm)<\/em>:<br \/>\n<img src=\"https:\/\/nasnz.ronella.xyz\/wordpress\/wp-content\/uploads\/2022\/09\/jwt-realm.png\" alt=\"jwt-realm\" \/><\/p>\n<\/li>\n<li>\n<p><strong>Create<\/strong> a <strong>new client<\/strong> as follows:<\/p>\n<ol>\n<li>\n<p><strong>Ensure<\/strong> that <strong>OpenID Connect<\/strong> is the <strong>Client type<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Provide<\/strong> a <strong>Client ID<\/strong> <em>(e.g. jwtclient)<\/em>.<\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Next button<\/strong>.<\/p>\n<p><img src=\"https:\/\/nasnz.ronella.xyz\/wordpress\/wp-content\/uploads\/2022\/09\/client-general-settings.png\" alt=\"client-general-settings\" \/><\/p>\n<\/li>\n<li>\n<p><strong>Enable<\/strong> the <strong>Client authentication<\/strong>.<\/p>\n<\/li>\n<li>\n<p>In the Authentication flow, <strong>unselect<\/strong> the <strong>standard flow<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Save button<\/strong>.<\/p>\n<p><img src=\"https:\/\/nasnz.ronella.xyz\/wordpress\/wp-content\/uploads\/2022\/09\/client-capability-config.png\" alt=\"client-capability-config\" \/><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p><strong>Create<\/strong> a <strong>new user<\/strong> as follows:<\/p>\n<ol>\n<li>\n<p><strong>Fill-in<\/strong> the <strong>username field<\/strong> <em>(e.g. testuser)<\/em>.<\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Create button<\/strong>. <\/p>\n<p><img src=\"https:\/\/nasnz.ronella.xyz\/wordpress\/wp-content\/uploads\/2022\/09\/user-create.png\" alt=\"user-create\" \/><\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Credentials tab<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Set password button<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Fill-in<\/strong> the <strong>Password field<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Fill-in<\/strong> the <strong>Password confirmation field<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Turn-off temporary<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Save button<\/strong>.<\/p>\n<p><img src=\"https:\/\/nasnz.ronella.xyz\/wordpress\/wp-content\/uploads\/2022\/09\/user-password.png\" alt=\"user-password\" \/><\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Save password button<\/strong>.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>Using Postman for Testing<\/h2>\n<ol>\n<li>\n<p>Create a <strong>post request<\/strong> to the following address format:<\/p>\n<pre><code>http:\/\/localhost:8080\/realms\/&lt;TARGET_REALM&gt;\/protocol\/openid-connect\/token<\/code><\/pre>\n<p><strong>Example<\/strong><\/p>\n<blockquote>\n<p>Using the <strong>jwtrealm<\/strong> as the <strong>TARGET_REALM<\/strong> <em>(i.e. configured in the previous section)<\/em>.<\/p>\n<\/blockquote>\n<p><a href=\"http:\/\/localhost:8080\/realms\/jwtrealm\/protocol\/openid-connect\/token\">http:\/\/localhost:8080\/realms\/jwtrealm\/protocol\/openid-connect\/token<\/a><\/p>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Body tab<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Select x-www-form-url-encoded<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Add<\/strong> the <strong>following entries<\/strong>:<\/p>\n<table>\n<thead>\n<tr>\n<th>Key<\/th>\n<th>Value<\/th>\n<th>Comment<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>client_id<\/td>\n<td>jwtclient<\/td>\n<td>This is the <strong>client<\/strong> configured earlier.<\/td>\n<\/tr>\n<tr>\n<td>grant_type<\/td>\n<td>password<\/td>\n<td>This is for <strong>direct access grant type<\/strong>.<\/td>\n<\/tr>\n<tr>\n<td>client_secret<\/td>\n<td>&lt;Client secret&gt;<\/td>\n<td>This can be found in the <strong>jwtclient <em>(i.e. configured earlier)<\/em> client credentials tab<\/strong>.<\/p>\n<p><img src=\"https:\/\/nasnz.ronella.xyz\/wordpress\/wp-content\/uploads\/2022\/09\/client-secret.png\" alt=\"client-secret\" \/><\/td>\n<\/tr>\n<tr>\n<td>scope<\/td>\n<td>openid<\/td>\n<td>The <strong>openid scope is required<\/strong>; to indicate that the application intends to use OIDC to verify the user's identity.<\/td>\n<\/tr>\n<tr>\n<td>username<\/td>\n<td>testuser<\/td>\n<td>This is the <strong>user<\/strong> configured earlier.<\/td>\n<\/tr>\n<tr>\n<td>password<\/td>\n<td>&lt;password&gt;<\/td>\n<td>This is the <strong>password<\/strong> for the user that is configured earlier.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li>\n<p><strong>Click<\/strong> the <strong>Send button<\/strong>.<\/p>\n<p><img src=\"https:\/\/nasnz.ronella.xyz\/wordpress\/wp-content\/uploads\/2022\/09\/postman-request.png\" alt=\"postman-request\" \/><\/p>\n<\/li>\n<\/ol>\n<h3>Success Output<\/h3>\n<blockquote>\n<p>The success output is in the following format.<\/p>\n<\/blockquote>\n<pre><code class=\"language-json\">{\n    &quot;access_token&quot;: &quot;The access token.&quot;,\n    &quot;expires_in&quot;: &quot;Access token expiration.&quot;,\n    &quot;refresh_expires_in&quot;: &quot;Refresh token expiration&quot;,\n    &quot;refresh_token&quot;: &quot;The refresh token.&quot;,\n    &quot;token_type&quot;: &quot;Bearer&quot;,\n    &quot;id_token&quot;: &quot;The ID token.&quot;,\n    &quot;not-before-policy&quot;: 0,\n    &quot;session_state&quot;: &quot;The session state.&quot;,\n    &quot;scope&quot;: &quot;openid profile email&quot;\n}<\/code><\/pre>\n<blockquote>\n<p>You paste the encoded token to the following website to decode its content:<\/p>\n<p><a href=\"https:\/\/jwt.io\/\">https:\/\/jwt.io\/<\/a><\/p>\n<\/blockquote>\n<h3>Invalid Credential Output<\/h3>\n<pre><code class=\"language-json\">{\n    &quot;error&quot;: &quot;invalid_grant&quot;,\n    &quot;error_description&quot;: &quot;Invalid user credentials&quot;\n}<\/code><\/pre>\n<p><strong>Related Post<\/strong><br \/>\n<a href=\"https:\/\/www.ronella.xyz\/?p=1577\" title=\"THE RESOURCE OWNER PASSWORD CREDENTIAL (ROPC) GRANT TYPE\">THE RESOURCE OWNER PASSWORD CREDENTIAL (ROPC) GRANT TYPE<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pre-requisite Keycloak 19^1 Creating a New Client and User Sign in to keycloak admin console using the following address: Must know a valid credential. http:\/\/localhost:8080\/admin\/ Switch or create a realm that is NOT a master realm (i.e. leave the master realms for keycloak usage only), like the following (i.e. jwtrealm): Create a new client as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[77,23],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1563"}],"collection":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1563"}],"version-history":[{"count":4,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1563\/revisions"}],"predecessor-version":[{"id":1580,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1563\/revisions\/1580"}],"wp:attachment":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}