{"id":10,"date":"2022-10-11T14:10:53","date_gmt":"2022-10-11T14:10:53","guid":{"rendered":"https:\/\/bit-development.nl\/?page_id=10"},"modified":"2022-10-22T20:28:22","modified_gmt":"2022-10-22T20:28:22","slug":"spring-cloud-gateway","status":"publish","type":"page","link":"https:\/\/bit-development.nl\/?page_id=10","title":{"rendered":"Spring Cloud Gateway + Keycloack integration"},"content":{"rendered":"\n<p>In this article we will work on integrating Spring Cloud Gateway with Keycloack to implement security and role-based access control within our microserves landscape. The Spring Cloud Gateway will act as a single point of contact for the outside world and routes all requests to underlying microservices. We will configure the Gateway in such a way that it passes the authentication token to the microservices by using token relay.<\/p>\n\n\n\n<p><strong>Setup Keycloack with Docker<\/strong><\/p>\n\n\n\n<p>We will first configure and run a Keycloack server with a Docker image. To do this, put the following content in a docker-compose.yml file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">version: '3.7'\n\nnetworks:\n  local:\n    name: local\n    driver: bridge\n\nservices:\n  keycloak:\n    image: quay.io\/keycloak\/keycloak:19.0.3\n    command: start-dev\n    ports:\n      - '8888:8080'\n    environment:\n      - KEYCLOAK_ADMIN=admin\n      - KEYCLOAK_ADMIN_PASSWORD=admin\n    volumes:\n      - .\/keycloak_data:\/opt\/jboss\/keycloak\/standalone\/data\/\n    networks:\n      - local<\/pre>\n\n\n\n<p>With this configuration Keycloack will listen on localhost:8888. We have also created a volume (optional) so Keycloak persists it&#8217;s data on our machine. This will prevent that we have to configure Keycloack each time after we shut down the Docker container. Then we can start Keycloak by running the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker-compose up<\/pre>\n\n\n\n<p><strong>Configure Keycloack<\/strong><\/p>\n\n\n\n<p>After the Keycloack container is running we can navigate to the admin console, which in our case will run at <a href=\"http:\/\/localhost:8888\/admin\/master\/console\">http:\/\/localhost:8888\/admin\/master\/console<\/a>. The admin username and password which we have configured in the docker-compose.yml file can be used to access the console. <\/p>\n\n\n\n<p>First we will create a new realm for this project. This can be done by clicking on the dropdown and selecting &#8216;Create Realm&#8217;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" src=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image.png\" alt=\"\" class=\"wp-image-26\" width=\"205\" height=\"248\" srcset=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image.png 543w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-248x300.png 248w\" sizes=\"(max-width: 205px) 100vw, 205px\" \/><\/figure>\n\n\n\n<p>Then we will provide our Realm name and click, make sure the &#8216;Enabled&#8217; checkbox is checked and click on &#8216;Create&#8217;. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-1-1024x413.png\" alt=\"\" class=\"wp-image-28\" width=\"702\" height=\"283\" srcset=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-1-1024x413.png 1024w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-1-300x121.png 300w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-1-768x310.png 768w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-1-1536x619.png 1536w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-1-2048x826.png 2048w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/figure>\n\n\n\n<p>Now that we have created our Realm we are able to create a new Client. The Client will be our Spring Cloud Gateway application which will connect to the Keycloack instance. To create the Client click on &#8216;Clients&#8217; and then &#8216;Create client&#8217;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"291\" src=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-3-1024x291.png\" alt=\"\" class=\"wp-image-31\" srcset=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-3-1024x291.png 1024w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-3-300x85.png 300w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-3-768x218.png 768w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-3-1536x436.png 1536w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-3.png 2034w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>On the next screen you have to provide the Client type, which will be &#8216;OpenID Connect&#8217; for this tutorial. Also provide the Client ID, this can be whatever you like, but &#8216;spring-gateway-client&#8217; will be a good descriptive name. The Name and description fields are optional and can be left blank. Then you can click on &#8216;Next&#8217;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"600\" src=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-4-1024x600.png\" alt=\"\" class=\"wp-image-33\" srcset=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-4-1024x600.png 1024w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-4-300x176.png 300w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-4-768x450.png 768w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-4-1536x900.png 1536w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-4-2048x1200.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>On the next page you should make sure the Client authentication toggle is on. Also the Standard flow and Direct access grants should be checked, but they should already be by default. Then save the new client.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"773\" src=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-5-1024x773.png\" alt=\"\" class=\"wp-image-35\" srcset=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-5-1024x773.png 1024w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-5-300x226.png 300w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-5-768x580.png 768w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-5-1536x1159.png 1536w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-5-2048x1546.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>After the client is created we will be send to the client details page. On this page we have to set the Valid redirect URIs. This URI will be called after a successful authentication attempt. Since our Spring Cloud Gateway application (which will run on port 8080 in this tutorial) will be used as a single point of contact, we will add the default Keycloak callback URI http:\/\/localhost:8080\/login\/oauth2\/code\/keycloak and save it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"592\" src=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-6-1024x592.png\" alt=\"\" class=\"wp-image-37\" srcset=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-6-1024x592.png 1024w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-6-300x173.png 300w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-6-768x444.png 768w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-6-1536x887.png 1536w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-6-2048x1183.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>At this point it is good to know that we will also need the client secret which is generated by Keycloak. The secret can be found in the Credentials section on the details page.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"551\" src=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-7-1024x551.png\" alt=\"\" class=\"wp-image-39\" srcset=\"https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-7-1024x551.png 1024w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-7-300x162.png 300w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-7-768x414.png 768w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-7-1536x827.png 1536w, https:\/\/bit-development.nl\/wp-content\/uploads\/2022\/10\/image-7-2048x1103.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>For now we have configured Keycloak correctly. We will now first setup the<strong> <\/strong>Spring Cloud Gateway application. <\/p>\n\n\n\n<p><strong>Setup Spring Cloud Gateway application<\/strong><\/p>\n\n\n\n<p>Now we will create a new Spring Boot application, this can be done from your favorite IDE, or go to <a rel=\"noreferrer noopener\" href=\"https:\/\/start.spring.io\/\" target=\"_blank\">https:\/\/start.spring.io<\/a>.<\/p>\n\n\n\n<ul><li>Gateway<\/li><li>OAuth2 Client<\/li><\/ul>\n\n\n\n<p>When the project is created we will first edit the application.yml file. There are some properties that have to match with our Keycloak configuration. The issuer-uri have to match with the realm you have created in Keycloak. Also the client-id and redirect-uri properties have to match as configured in Keycloak. The client secret can be found on the  Keycloak dashboard as mentioned in the previous step.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">server:<br>  port: 8080<br>  <br>spring:<br>  application:<br>    name: api-gateway<br>  security:<br>    oauth2:<br>      client:<br>        provider:<br>          my-keycloak-provider:<br>            issuer-uri: http:\/\/localhost:8888\/realms\/BIT-development<br>        registration:<br>          keycloak-spring-gateway-client:<br>            provider: my-keycloak-provider<br>            client-id: spring-gateway-client<br>            client-secret: UdwIHiDOqunfiniGdDsS56TXKGaq7x2p<br>            authorization-grant-type: authorization_code<br>            redirect-uri: '{baseUrl}\/login\/oauth2\/code\/keycloak'<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In this article we will work on integrating Spring Cloud Gateway with Keycloack to implement security and role-based access control within our microserves landscape. The Spring Cloud Gateway will act [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}}},"_links":{"self":[{"href":"https:\/\/bit-development.nl\/index.php?rest_route=\/wp\/v2\/pages\/10"}],"collection":[{"href":"https:\/\/bit-development.nl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bit-development.nl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bit-development.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bit-development.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10"}],"version-history":[{"count":20,"href":"https:\/\/bit-development.nl\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions"}],"predecessor-version":[{"id":40,"href":"https:\/\/bit-development.nl\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions\/40"}],"wp:attachment":[{"href":"https:\/\/bit-development.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}