{"id":89400,"date":"2019-03-18T08:55:04","date_gmt":"2019-03-18T06:55:04","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=89400"},"modified":"2019-03-25T08:44:35","modified_gmt":"2019-03-25T06:44:35","slug":"secure-service-spring-microservices","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2019\/03\/secure-service-spring-microservices.html","title":{"rendered":"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0"},"content":{"rendered":"<p><span style=\"font-size: 20px;\"><b>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever.<\/b> Tired of building the same login screens over and over? <a href=\"https:\/\/developer.okta.com\/signup\/?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Try the Okta API for hosted authentication, authorization, and multi-factor auth.<\/a><\/span><\/p>\n<p>Building a microservices architecture is possible with minimal code if you use Spring Boot, Spring Cloud, and Spring Cloud Config. Package everything up in Docker containers and you can run everything using Docker Compose. If you\u2019re communicating between services, you can ensure your services are somewhat secure by not exposing their ports in your&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>&nbsp;file.<\/p>\n<p>But what happens if someone accidentally exposes the ports of your microservice apps? Will they still be secure or can anyone access their data?<\/p>\n<p>In this post, I\u2019ll show you how to use HTTPS and OAuth 2.0 to secure service-to-service communication.<\/p>\n<h2 class=\"wp-block-heading\" id=\"develop-a-microservices-stack-with-spring-boot-spring-cloud-and-spring-cloud-config\">Develop a Microservices Stack with Spring Boot, Spring Cloud, and Spring Cloud Config<\/h2>\n<p>I\u2019m going to shortcut the process of building a full microservices stack with Spring Boot, Spring Cloud, and Spring Cloud Config. My buddy, Raphael, wrote a post on how to&nbsp;<a href=\"https:\/\/developer.okta.com\/blog\/2019\/02\/28\/spring-microservices-docker?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">build Spring microservices and Dockerize them for production<\/a>. You can use his example app as a starting point. Clone the&nbsp;<a href=\"https:\/\/github.com\/oktadeveloper\/okta-spring-microservices-docker-example\">okta-spring-microservices-docker-example<\/a>&nbsp;project:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">git clone https:\/\/github.com\/oktadeveloper\/okta-spring-microservices-docker-example.git spring-microservices-security\ncd spring-microservices-security\n<\/pre>\n<p>This project requires two OpenID Connect apps on Okta, one for development and one for production. You\u2019ll need to create each app on Okta if you didn\u2019t run through the aforementioned tutorial.<\/p>\n<h3 class=\"wp-block-heading\" id=\"create-openid-connect-apps-on-okta\">Create OpenID Connect Apps on Okta<\/h3>\n<p>You can register for a&nbsp;<a href=\"https:\/\/developer.okta.com\/signup\/?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">free developer account<\/a>&nbsp;that will allow you to have up to 1000 monthly active users for $0. That should be plenty for this example.<\/p>\n<p>Why Okta? Because authentication is no fun to write. Okta has Authentication and User Management APIs that allow you to develop your apps faster. Our API and SDKs make it easy for you to authenticate, manage, and secure your users in minutes.<\/p>\n<p>After creating your account, create a new Web Application in Okta\u2019s dashboard (<strong>Applications<\/strong>&nbsp;&gt;&nbsp;<strong>Add Application<\/strong>). Give the app a name you\u2019ll remember, duplicate the existing Login redirect URI and make it use HTTPS. Click&nbsp;<strong>Done<\/strong>.<\/p>\n<p>The result should look similar to the screenshot below.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/oidc-web-app-1000x1024.png\" alt=\"Secure Service\" class=\"wp-image-89408\" width=\"750\" height=\"768\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/oidc-web-app-1000x1024.png 1000w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/oidc-web-app-293x300.png 293w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/oidc-web-app-768x787.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/oidc-web-app.png 1476w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure>\n<\/div>\n<p>Create another app for production. I called mine<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Prod Microservices<\/code>.<\/p>\n<p>In the project you cloned, modify<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">config\/school-ui.properties<\/code>&nbsp;to have the settings from your dev app.<\/p>\n<pre class=\"gutter: false;brush:bash\">okta.oauth2.issuer=https:\/\/{yourOktaDomain}\/oauth2\/default\nokta.oauth2.clientId={devClientId}\nokta.oauth2.clientSecret={devClientId}<\/pre>\n<p>These settings will be used when running your apps individually using Maven. The production settings are used when running with Docker Compose. Modify<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">config-data\/school-ui-production.properties<\/code>to have the settings from your production app.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">okta.oauth2.clientId={prodClientId}\nokta.oauth2.clientSecret={prodClientId}\n<\/pre>\n<p>You can see that<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">spring.profiles.active<\/code>turns on the production profile in<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">school-ui:\n  image: developer.okta.com\/microservice-docker-school-ui:0.0.1-SNAPSHOT\n  environment:\n    - JAVA_OPTS=\n      -DEUREKA_SERVER=http:\/\/discovery:8761\/eureka\n      -Dspring.profiles.active=production\n  restart: on-failure\n  depends_on:\n    - discovery\n    - config\n  ports:\n    - 8080:8080\n<\/pre>\n<p>Docker Compose runs from a directory above the apps, and it reads its data from a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">config-data<\/code>&nbsp;directory. For this reason, you\u2019ll need to copy these properties files into this directory. Run the following commands from the root of this project.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">cp config\/*.properties config-data\/.<\/pre>\n<h2 class=\"wp-block-heading\" id=\"start-your-spring-microservices-stack-with-docker-compose\">Start Your Spring Microservices Stack with Docker Compose<\/h2>\n<p>This project has an aggregator<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">pom.xml<\/code>&nbsp;in its root directory that will allow you to build all the projects with one command. Run the following Maven commands to build, test, and build Docker images for each project.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">mvn clean install<\/pre>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If you don\u2019t have Maven installed, you can install it with&nbsp;<a href=\"https:\/\/sdkman.io\/\">SDKMAN!<\/a><code class=\"highlighter-rouge\" style=\"font-size: 13px;\">sdk install maven<\/code><\/p>\n<\/blockquote>\n<p>When the process completes, start all the apps { config, discovery, school-service, and school-ui } with Docker Compose. See&nbsp;<a href=\"https:\/\/docs.docker.com\/compose\/install\/\">Install Docker Compose<\/a>&nbsp;if you don\u2019t have it installed.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">docker-compose up -d<\/pre>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>You can use&nbsp;<a href=\"https:\/\/kitematic.com\/\">Kitematic<\/a>&nbsp;to watch the logs of each app as it starts up.<\/p>\n<\/blockquote>\n<p>Navigate to<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"http:\/\/localhost:8080\/\">http:\/\/localhost:8080<\/a><\/code>&nbsp;in your favorite browser. You should be able to log in and see a list of school classes after doing so.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/school-ui-1024x515.png\" alt=\"Secure Service\" class=\"wp-image-89409\" width=\"768\" height=\"386\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/school-ui-1024x515.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/school-ui-300x151.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/school-ui-768x386.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/school-ui.png 1798w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<h3 class=\"wp-block-heading\" id=\"spring-security-and-oauth-2-0\">Spring Security and OAuth 2.0<\/h3>\n<p>This example uses&nbsp;<a href=\"https:\/\/github.com\/okta\/okta-spring-boot\">Okta\u2019s Spring Boot Starter<\/a>, which is a thin layer on top of Spring Security. The Okta starter simplifies configuration and does audience validation in the access token. It also allows you to specify the claim that will be used to create Spring Security authorities.<\/p>\n<p>The<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>&nbsp;file doesn\u2019t expose the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>&nbsp;to the outside world. It does this by not specifying<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">ports<\/code>.<\/p>\n<p>The<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-ui<\/code>&nbsp;project has a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SchoolController<\/code>&nbsp;class that talks to the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>&nbsp;using Spring\u2019s<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">RestTemplate<\/code>.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">@GetMapping(\"\/classes\")\n@PreAuthorize(\"hasAuthority('SCOPE_profile')\")\npublic ResponseEntity&lt;List&lt;TeachingClassDto&gt;&gt; listClasses() {\n\n    return restTemplate\n            .exchange(\"http:\/\/school-service\/class\", HttpMethod.GET, null,\n                    new ParameterizedTypeReference&lt;List&lt;TeachingClassDto&gt;&gt;() {});\n}<\/pre>\n<p>You\u2019ll notice there is security on this class\u2019s endpoint, but no security exists between the services. I\u2019ll show you how to solve that in the steps below.<\/p>\n<p>First, expose the port of<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>&nbsp;to simulate someone fat-fingering the configuration. Change the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>configuration in<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>&nbsp;to expose its port.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">school-service:\n  image: developer.okta.com\/microservice-docker-school-service:0.0.1-SNAPSHOT\n  environment:\n    - JAVA_OPTS=\n      -DEUREKA_SERVER=http:\/\/discovery:8761\/eureka\n  depends_on:\n    - discovery\n    - config\n  ports:\n    - 8081:8081<\/pre>\n<p>Restart everything with Docker Compose:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">docker-compose down\ndocker-compose up -d<\/pre>\n<p>You\u2019ll see that you don\u2019t need to authenticate to see data at&nbsp;<code><a class=\"bare\" href=\"http:\/\/localhost:8081\/\">http:\/\/localhost:8081<\/a><\/code>. Yikes! \ud83d\ude31<\/p>\n<p><strong>Make sure<\/strong>&nbsp;to shut down all your Docker containers before proceeding to the next section.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">docker-compose down<\/pre>\n<h2 class=\"wp-block-heading\" id=\"https-everywhere\">HTTPS Everywhere!<\/h2>\n<p>HTTPS stands for &#8220;Secure&#8221; HTTP. HTTPS connections are encrypted and its contents are vastly more difficult to read than HTTP connections. There\u2019s been a big movement in recent years to use HTTPS everywhere, even when developing. There are issues you might run into when running with HTTPS, and it\u2019s good to catch them early.<\/p>\n<p><a href=\"https:\/\/letsencrypt.org\/\">Let\u2019s Encrypt<\/a>&nbsp;is a certificate authority that offers free HTTPS certificates. It also has APIs to automate their renewal. In short, it makes HTTPS so easy, there\u2019s no reason not to use it! See&nbsp;<a href=\"https:\/\/developer.okta.com\/blog\/2019\/02\/19\/add-social-login-to-spring-boot#configure-the-custom-domain-name-for-your-spring-boot-app?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Add Social Login to Your JHipster App<\/a>&nbsp;for instructions on how to use<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">certbot<\/code>with Let\u2019s Encrypt to generate certificates.<\/p>\n<p>I also encourage you to checkout&nbsp;<a href=\"https:\/\/github.com\/creactiviti\/spring-boot-starter-acme\">Spring Boot Starter ACME<\/a>. This is a Spring Boot module that simplifies generating certificates using Let\u2019s Encrypt and the Automatic Certificate Management Environment (ACME) protocol.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h3 class=\"wp-block-heading\" id=\"make-local-tls-easy-with-mkcert\">Make Local TLS Easy with mkcert<\/h3>\n<p>I recently found a tool called&nbsp;<a href=\"https:\/\/github.com\/FiloSottile\/mkcert\">mkcert<\/a> that allows creating<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">localhost<\/code>&nbsp;certificates. You can install it using Homebrew on macOS<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">brew install mkcert\nbrew install nss # Needed for Firefox<\/pre>\n<p>If you\u2019re on Linux, you\u2019ll need to install<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">certutil<\/code>&nbsp;first:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">sudo apt install libnss3-tools<\/pre>\n<p>Then run the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">brew install mkcert<\/code>&nbsp;command using&nbsp;<a href=\"http:\/\/linuxbrew.sh\/\">Linuxbrew<\/a>. Windows users can&nbsp;<a href=\"https:\/\/github.com\/FiloSottile\/mkcert#windows\">use Chocolately or Scoop<\/a>.<\/p>\n<p>Execute the following<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">mkcert<\/code>&nbsp;commands to generate a certificate for<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">localhost<\/code>,<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">127.0.0.1<\/code>, your machine\u2019s name, and the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">discovery<\/code>&nbsp;host (as referenced in<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>).<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">mkcert -install\nmkcert localhost 127.0.0.1 ::1 `hostname` discovery<\/pre>\n<p>If this generates files with a number in them, rename the files so they don\u2019t have a number.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">mv localhost+2.pem localhost.pem\nmv localhost+2-key.pem localhost-key.pem<\/pre>\n<h3 class=\"wp-block-heading\" id=\"https-with-spring-boot\">HTTPS with Spring Boot<\/h3>\n<p>Spring Boot doesn\u2019t support certificates with the&nbsp;<a href=\"https:\/\/tools.ietf.org\/html\/rfc1421\">PEM<\/a>&nbsp;extension, but you can convert it to a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">PKCS12<\/code>&nbsp;extension, which Spring Boot does support. You can use OpenSSL to convert the certificate and private key to PKCS12. This will be necessary for Let\u2019s Encrypt generated certificates too.<\/p>\n<p>Run<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">openssl<\/code>&nbsp;to convert the certificate:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">openssl pkcs12 -export -in localhost.pem -inkey \\\nlocalhost-key.pem -out keystore.p12 -name bootifulsecurity<\/pre>\n<p>Specify a password when prompted.<\/p>\n<p>Create an<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">https.env<\/code>&nbsp;file at the root of your project and specify the following properties to enable HTTPS.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">export SERVER_SSL_ENABLED=true\nexport SERVER_SSL_KEY_STORE=..\/keystore.p12\nexport SERVER_SSL_KEY_STORE_PASSWORD={yourPassword}\nexport SERVER_SSL_KEY_ALIAS=bootifulsecurity\nexport SERVER_SSL_KEY_STORE_TYPE=PKCS12\n<\/pre>\n<p>Update the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.gitignore<\/code>&nbsp;file to exclude<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.env<\/code>&nbsp;files so the keystore password doesn\u2019t end up in source control.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">*.env<\/pre>\n<p>Run<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">source https.env<\/code>&nbsp;to set these environment variables. Or, even better, add this like to your<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.bashrc<\/code>&nbsp;or<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.zshrc<\/code>&nbsp;file so these variables are set for every new shell. Yes, you can also include them in each app\u2019s<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">application.properties<\/code>, but then you\u2019re storing secrets in source control. If you\u2019re not checking this example into source control, here are the settings you can copy\/paste.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">server.ssl.enabled=true\nserver.ssl.key-store=..\/keystore.p12\nserver.ssl.key-store-password: {yourPassword}\nserver.ssl.key-store-type: PKCS12\nserver.ssl.key-alias: bootifulsecurity\n<\/pre>\n<p>Start the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">discovery<\/code>&nbsp;app:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">cd discovery\nsource ..\/https.env\nmvn spring-boot:run\n<\/pre>\n<p>Then confirm you can access it at<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"https:\/\/localhost:8761\/\">https:\/\/localhost:8761<\/a><\/code>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/secure-discovery-1024x605.png\" alt=\"Secure Service\" class=\"wp-image-89410\" width=\"768\" height=\"454\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/secure-discovery-1024x605.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/secure-discovery-300x177.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/03\/secure-discovery-768x454.png 768w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Open<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>&nbsp;and change all instances of<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">http<\/code>&nbsp;to<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">https<\/code>. Edit<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-ui\/src\/main\/java\/\u2026\u200b\/ui\/controller\/SchoolController.java<\/code>&nbsp;to change the call to<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>&nbsp;to use HTTPS.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">return restTemplate\n        .exchange(\"https:\/\/school-service\/class\", HttpMethod.GET, null,\n                new ParameterizedTypeReference&lt;List&lt;TeachingClassDto&gt;&gt;() {});\n<\/pre>\n<p>Update<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">{config,school-service,school-ui}\/src\/main\/resources\/application.properties<\/code>&nbsp;to add properties that cause each instance to&nbsp;<a href=\"http:\/\/cloud.spring.io\/spring-cloud-static\/spring-cloud.html#_registering_a_secure_application\">register as a secure application<\/a>.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">eureka.instance.secure-port-enabled=true\neureka.instance.secure-port=${server.port}\neureka.instance.status-page-url=https:\/\/${eureka.hostname}:${server.port}\/actuator\/info\neureka.instance.health-check-url=https:\/\/${eureka.hostname}:${server.port}\/actuator\/health\neureka.instance.home-page-url=https:\/\/${eureka.hostname}${server.port}\/\n<\/pre>\n<p>Also, change the Eureka address in each<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">application.properties<\/code>&nbsp;(and in<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">bootstrap.yml<\/code>) to be<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"https:\/\/localhost:8761\/eureka\">https:\/\/localhost:8761\/eureka<\/a><\/code>.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>The<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">application.properties<\/code>&nbsp;in the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-ui<\/code>&nbsp;project doesn\u2019t have a port specified. You\u2019ll need to add<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">server.port=8080<\/code>.<\/p>\n<\/blockquote>\n<p>At this point, you should be able to start all your apps by running the following in each project (in separate terminal windows).<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">source ..\/https.env\n.\/mvnw spring-boot:start\n<\/pre>\n<p>Confirm it all works at<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"https:\/\/localhost:8080\/\">https:\/\/localhost:8080<\/a><\/code>. Then kill everything with<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">killall java<\/code>.<\/p>\n<h2 class=\"wp-block-heading\" id=\"using-https-with-docker-compose\">Using HTTPS with Docker Compose<\/h2>\n<p>Docker doesn\u2019t read from environment variables, it doesn\u2019t know about your local CA (Certificate Authority), and you can\u2019t add files from a parent directory to an image.<\/p>\n<p>To fix this, you\u2019ll need to copy<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">keystore.p12<\/code>&nbsp;and<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">localhost.pem<\/code>&nbsp;into each project\u2019s directory. The first will be used for Spring Boot, and the second will be added to the Java Keystore on each image.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">cp localhost.pem keystore.p12 config\/.\ncp localhost.pem keystore.p12 discovery\/.\ncp localhost.pem keystore.p12 school-service\/.\ncp localhost.pem keystore.p12 school-ui\/.<\/pre>\n<p>Then modify each project\u2019s <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Dockerfile<\/code> to copy the certificate and add it to its trust store.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:sql\">FROM openjdk:8-jdk-alpine\nVOLUME \/tmp\nADD target\/*.jar app.jar\nADD keystore.p12 keystore.p12\nUSER root\nCOPY localhost.pem $JAVA_HOME\/jre\/lib\/security\nRUN \\\n    cd $JAVA_HOME\/jre\/lib\/security \\\n    &amp;&amp; keytool -keystore cacerts -storepass changeit -noprompt \\\n    -trustcacerts -importcert -alias bootifulsecurity -file localhost.pem\nENV JAVA_OPTS=\"\"\nENTRYPOINT [ \"sh\", \"-c\", \"java $JAVA_OPTS -Djava.security.egd=file:\/dev\/.\/urandom -jar \/app.jar\" ]\n<\/pre>\n<p>Then create a <code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.env<\/code> file with environment variables for Spring Boot and HTTPS.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">SERVER_SSL_ENABLED=true\nSERVER_SSL_KEY_STORE=keystore.p12\nSERVER_SSL_KEY_STORE_PASSWORD={yourPassword}\nSERVER_SSL_KEY_ALIAS=bootifulsecurity\nSERVER_SSL_KEY_STORE_TYPE=PKCS12\nEUREKA_INSTANCE_HOSTNAME={yourHostname}\n<\/pre>\n<p>You can get the value for<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">{yourHostname}<\/code>&nbsp;by running<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">hostname<\/code>.<\/p>\n<p>Docker Compose has an &#8220;env_file&#8221; configuration option that allows you to read this file for environment variables. Update<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>&nbsp;to specify an<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">env_file<\/code>&nbsp;for each application.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:js\">version: '3'\nservices:\n  discovery:\n    env_file:\n      - .env\n    ...\n  config:\n    env_file:\n      - .env\n    ...\n  school-service:\n    env_file:\n      - .env\n    ...\n  school-ui:\n    env_file:\n      - .env\n    ...\n<\/pre>\n<p>You can make sure it\u2019s working by running<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose config<\/code>&nbsp;from your root directory.<\/p>\n<p>Run<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">mvn clean install<\/code>&nbsp;to rebuild all your Docker images with HTTPS enabled for Eureka registration. Then start all everything.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">docker-compose up -d<\/pre>\n<p>Now all your apps are running in Docker with HTTPS! Prove it at<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"https:\/\/localhost:8080\/\">https:\/\/localhost:8080<\/a><\/code>.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If your apps do not start up or can\u2019t talk to each other, make sure your hostname matches what you have in<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.env<\/code>.<\/p>\n<\/blockquote>\n<p>You can make one more security improvement: use OAuth 2.0 to secure your school-service API.<\/p>\n<h2 class=\"wp-block-heading\" id=\"api-security-with-oauth-2-0\">API Security with OAuth 2.0<\/h2>\n<p>Add the Okta Spring Boot Starter and Spring Cloud Config to<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service\/pom.xml<\/code>:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:xml\">&lt;dependency&gt;\n    &lt;groupId&gt;com.okta.spring&lt;\/groupId&gt;\n    &lt;artifactId&gt;okta-spring-boot-starter&lt;\/artifactId&gt;\n    &lt;version&gt;1.1.0&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-config&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n<\/pre>\n<p>Then create a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SecurityConfiguration.java<\/code>&nbsp;class in<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service\/src\/main\/java\/\u2026\u200b\/service\/configuration<\/code>:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">package com.okta.developer.docker_microservices.service.configuration;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.security.config.annotation.web.builders.HttpSecurity;\nimport org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;\n\n@Configuration\npublic class SecurityConfiguration extends WebSecurityConfigurerAdapter {\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http\n            .authorizeRequests().anyRequest().authenticated()\n            .and()\n            .oauth2ResourceServer().jwt();\n    }\n}\n<\/pre>\n<p>Create a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service\/src\/test\/resources\/test.properties<\/code>&nbsp;file and add properties so Okta\u2019s config passes, and it doesn\u2019t use discovery or the config server when testing.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">okta.oauth2.issuer=https:\/\/{yourOktaDomain}\/oauth2\/default\nokta.oauth2.clientId=TEST\nspring.cloud.discovery.enabled=false\nspring.cloud.config.discovery.enabled=false\nspring.cloud.config.enabled=false<\/pre>\n<p>Then modify<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">ServiceApplicationTests.java<\/code>&nbsp;to load this file for test properties:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">import org.springframework.test.context.TestPropertySource;\n\n...\n@TestPropertySource(locations=\"classpath:test.properties\")\npublic class ServiceApplicationTests {\n    ...\n}\n<\/pre>\n<p>Add a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service\/src\/main\/resources\/bootstrap.yml<\/code>&nbsp;file that allows this instance to read its configuration from Spring Cloud Config.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">eureka:\n  client:\n    serviceUrl:\n      defaultZone: ${EUREKA_SERVER:https:\/\/localhost:8761\/eureka}\nspring:\n  application:\n    name: school-service\n  cloud:\n    config:\n      discovery:\n        enabled: true\n        serviceId: CONFIGSERVER\n      failFast: true\n<\/pre>\n<p>Then copy<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">config\/school-ui.properties<\/code>&nbsp;to have a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>&nbsp;equivalent.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">cp config\/school-ui.properties config\/school-service.properties<\/pre>\n<p>For Docker Compose, you\u2019ll also need to create a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">config-data\/school-service.properties<\/code>&nbsp;with the following settings:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">okta.oauth2.issuer=https:\/\/{yourOktaDomain}\/oauth2\/default\nokta.oauth2.clientId={prodClientId}\nokta.oauth2.clientSecret={prodClientId}\n<\/pre>\n<p>You\u2019ll also need to modify<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">docker-compose.yml<\/code>&nbsp;so the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>&nbsp;restarts on failure.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">school-service:\n  ...\n  restart: on-failure<\/pre>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>You could create a service app on Okta that uses client credentials, but this post is already complex enough. See&nbsp;<a href=\"https:\/\/developer.okta.com\/blog\/2018\/04\/02\/client-creds-with-spring-boot?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Secure Server-to-Server Communication with Spring Boot and OAuth 2.0<\/a>&nbsp;for more information on that approach.<\/p>\n<\/blockquote>\n<p>The last step you\u2019ll need to do is modify&nbsp;<code>SchoolController<\/code>&nbsp;(in the&nbsp;<code>school-ui<\/code>&nbsp;project) to add an OAuth 2.0 access token to the request it makes to&nbsp;<code>school-server<\/code>.<\/p>\n<div class=\"exampleblock\">\n<div class=\"title\"><span style=\"color: #800000;\">Example 1. Add an AccessToken to RestTemplate<\/span><\/div>\n<\/div>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">package com.okta.developer.docker_microservices.ui.controller;\n\nimport com.okta.developer.docker_microservices.ui.dto.TeachingClassDto;\nimport org.springframework.core.ParameterizedTypeReference;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.HttpRequest;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.http.client.ClientHttpRequestExecution;\nimport org.springframework.http.client.ClientHttpRequestInterceptor;\nimport org.springframework.http.client.ClientHttpResponse;\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springframework.security.core.annotation.AuthenticationPrincipal;\nimport org.springframework.security.oauth2.client.OAuth2AuthorizedClient;\nimport org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;\nimport org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;\nimport org.springframework.security.oauth2.core.OAuth2AccessToken;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.client.RestTemplate;\nimport org.springframework.web.servlet.ModelAndView;\n\nimport java.io.IOException;\nimport java.util.List;\n\n@Controller\n@RequestMapping(\"\/\")\npublic class SchoolController {\n\n    private final OAuth2AuthorizedClientService authorizedClientService;\n    private final RestTemplate restTemplate;\n\n    public SchoolController(OAuth2AuthorizedClientService clientService,\n                            RestTemplate restTemplate) { (1)\n        this.authorizedClientService = clientService;\n        this.restTemplate = restTemplate;\n    }\n\n    @RequestMapping(\"\")\n    public ModelAndView index() {\n        return new ModelAndView(\"index\");\n    }\n\n    @GetMapping(\"\/classes\")\n    @PreAuthorize(\"hasAuthority('SCOPE_profile')\")\n    public ResponseEntity&lt;List&lt;TeachingClassDto&gt;&gt; listClasses(\n            @AuthenticationPrincipal OAuth2AuthenticationToken authentication) { (2)\n\n        OAuth2AuthorizedClient authorizedClient =\n                this.authorizedClientService.loadAuthorizedClient(\n                        authentication.getAuthorizedClientRegistrationId(),\n                        authentication.getName()); (3)\n\n        OAuth2AccessToken accessToken = authorizedClient.getAccessToken(); (4)\n        restTemplate.getInterceptors().add(getBearerTokenInterceptor(accessToken.getTokenValue())); (5)\n\n        return restTemplate\n                .exchange(\"https:\/\/school-service\/class\", HttpMethod.GET, null,\n                        new ParameterizedTypeReference&lt;List&lt;TeachingClassDto&gt;&gt;() {});\n    }\n\n    private ClientHttpRequestInterceptor getBearerTokenInterceptor(String accessToken) {\n        return (request, bytes, execution) -&gt; {\n            request.getHeaders().add(\"Authorization\", \"Bearer \" + accessToken);\n            return execution.execute(request, bytes);\n        };\n    }\n}\n<\/pre>\n<ol class=\"wp-block-list\">\n<li>Add an<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">OAuth2AuthorizedClientService<\/code> dependency to the constructor<\/li>\n<li>Inject an<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">OAuth2AuthenticationToken<\/code>&nbsp;into the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">listClasses()<\/code>&nbsp;method<\/li>\n<li>Create an<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">OAuth2AuthorizedClient<\/code>&nbsp;from the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">authentication<\/code><\/li>\n<li>Get the access token from the authorized client<\/li>\n<li>Add the access token to the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Authorization<\/code>&nbsp;header<\/li>\n<\/ol>\n<p>That\u2019s it! Since the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-ui<\/code>&nbsp;and the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-service<\/code>&nbsp;use the same OIDC app settings, the server will recognize and validate the access token (which is also a JWT), and allow access.<\/p>\n<p>At this point, you can choose to run all your apps individually with<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/mvnw spring-boot:run<\/code>&nbsp;or with Docker Compose. The latter method requires just a few commands.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">mvn clean install\ndocker-compose down\ndocker-compose up -d<\/pre>\n<h2 class=\"wp-block-heading\" id=\"use-http-basic-auth-for-secure-microservice-communication-with-eureka-and-spring-cloud-config\">Use HTTP Basic Auth for Secure Microservice Communication with Eureka and Spring Cloud Config<\/h2>\n<p>To improve security between your microservices, Eureka Server, and Spring Cloud Config, even more, you can add HTTP Basic Authentication. To do this, you\u2019ll need to add<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">spring-boot-starter-security<\/code>&nbsp;as a dependency in both the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">config<\/code>&nbsp;and<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">discovery<\/code>&nbsp;projects. Then you\u2019ll need to specify a<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">spring.security.user.password<\/code>&nbsp;for each and encrypt it. You can learn more about how to do this in&nbsp;<a href=\"https:\/\/cloud.spring.io\/spring-cloud-config\/single\/spring-cloud-config.html#_security\">Spring Cloud Config\u2019s security docs<\/a>.<\/p>\n<p>Once you have Spring Security configured in both projects, you can adjust the URLs to include a username and password in them. For example, here\u2019s what the setting will look like in the<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">school-ui<\/code>&nbsp;project\u2019s<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">bootstrap.yml<\/code>:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">eureka:\n  client:\n    serviceUrl:\n      defaultZone: ${EUREKA_SERVER:https:\/\/username:password@localhost:8761\/eureka}\n<\/pre>\n<p>You\u2019ll need to make a similar adjustment to the URLs in&nbsp;<code>docker-compose.yml<\/code>.<\/p>\n<h2 class=\"wp-block-heading\" id=\"enhance-your-knowledge-about-spring-microservices-docker-and-oauth-2-0\">Enhance Your Knowledge about Spring Microservices, Docker, and OAuth 2.0<\/h2>\n<p>This tutorial showed you how to make sure your service-to-service communications are secure in a microservices architecture. You learned how to use HTTPS everywhere and lock down your API with OAuth 2.0 and JWTs.<\/p>\n<p>You can find the source code for this example on GitHub at&nbsp;<a href=\"https:\/\/github.com\/oktadeveloper\/okta-spring-microservices-https-example\">oktadeveloper\/okta-spring-microservices-https-example<\/a>.<\/p>\n<p>If you\u2019d like to explore these topics a bit more, I think you\u2019ll like the following blog posts:<\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2019\/02\/28\/spring-microservices-docker?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Build Spring Microservices and Dockerize Them for Production<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2017\/06\/15\/build-microservices-architecture-spring-boot?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Build a Microservices Architecture for Microbrews with Spring Boot<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/05\/17\/microservices-spring-boot-2-oauth?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Build and Secure Microservices with Spring Boot 2.0 and OAuth 2.0<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/03\/01\/develop-microservices-jhipster-oauth?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Develop a Microservices Architecture with OAuth 2.0 and JHipster<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/04\/02\/client-creds-with-spring-boot?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Secure Server-to-Server Communication with Spring Boot and OAuth 2.0<\/a><\/li>\n<\/ul>\n<p>These blog posts were helpful in getting everything to work in this post:<\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/piotrminkowski.wordpress.com\/2018\/05\/21\/secure-discovery-with-spring-cloud-netflix-eureka\/\">Secure Discovery with Spring Cloud Netflix Eureka<\/a><\/li>\n<li><a href=\"https:\/\/dzone.com\/articles\/spring-boot-secured-by-lets-encrypt\">Spring Boot Secured By Let\u2019s Encrypt<\/a><\/li>\n<\/ul>\n<p>Got questions? Ask them in the comments below! If your question doesn\u2019t relate to this post, please post them to our&nbsp;<a href=\"https:\/\/devforum.okta.com\/\">Developer Forums<\/a>.<\/p>\n<p>To get notifications of more of our tech-heavy blog posts, follow us&nbsp;<a href=\"https:\/\/twitter.com\/oktadev\">@oktadev<\/a>&nbsp;on Twitter, or subscribe to our&nbsp;<a href=\"https:\/\/www.youtube.com\/channel\/UC5AMiWqFVFxF1q9Ya1FuZ_Q\">YouTube Channel<\/a>.<\/p>\n<p><a href=\"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">&#8220;Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0&#8221;<\/a>&nbsp;was originally published on the Okta developer blog on March 07, 2019. <\/p>\n<p><span style=\"font-size: 20px;\"><b>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever.<\/b> Tired of building the same login screens over and over? <a href=\"https:\/\/developer.okta.com\/signup\/?utm_campaign=text_website_all_multiple_dev_ciam_secure-service-to-service-spring_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Try the Okta API for hosted authentication, authorization, and multi-factor auth.<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever. Tired of building the same login screens over and over? Try the Okta API for hosted authentication, authorization, and multi-factor auth. Building a microservices architecture is possible with minimal code if you use Spring Boot, Spring Cloud, and Spring Cloud Config. Package everything &hellip;<\/p>\n","protected":false},"author":13127,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[960,533,30,854,992],"class_list":["post-89400","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-microservices","tag-oauth","tag-spring","tag-spring-boot","tag-spring-cloud"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0 - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn about Secure Service? Check our article explaining how to use HTTPS and OAuth 2.0 to secure service-to-service communication.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0 - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn about Secure Service? Check our article explaining how to use HTTPS and OAuth 2.0 to secure service-to-service communication.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2019-03-18T06:55:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-25T06:44:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Matt Raible\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mraible\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matt Raible\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/03\\\/secure-service-spring-microservices.html\"},\"author\":{\"name\":\"Matt Raible\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/54edd49deb980d7706e2af51514c3f7f\"},\"headline\":\"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0\",\"datePublished\":\"2019-03-18T06:55:04+00:00\",\"dateModified\":\"2019-03-25T06:44:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/03\\\/secure-service-spring-microservices.html\"},\"wordCount\":2162,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Microservices\",\"OAuth\",\"Spring\",\"Spring Boot\",\"Spring Cloud\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/03\\\/secure-service-spring-microservices.html\",\"url\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2\",\"name\":\"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0 - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2019-03-18T06:55:04+00:00\",\"dateModified\":\"2019-03-25T06:44:35+00:00\",\"description\":\"Interested to learn about Secure Service? Check our article explaining how to use HTTPS and OAuth 2.0 to secure service-to-service communication.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/03\\\/07\\\/spring-microservices-https-oauth2#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/54edd49deb980d7706e2af51514c3f7f\",\"name\":\"Matt Raible\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g\",\"caption\":\"Matt Raible\"},\"description\":\"Java Champion and Developer Advocate @okta with a passion for skiing, mtn biking, VWs, &amp; good beer.\",\"sameAs\":[\"https:\\\/\\\/developer.okta.com\",\"https:\\\/\\\/x.com\\\/mraible\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/matt-raible\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0 - Java Code Geeks","description":"Interested to learn about Secure Service? Check our article explaining how to use HTTPS and OAuth 2.0 to secure service-to-service communication.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2","og_locale":"en_US","og_type":"article","og_title":"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0 - Java Code Geeks","og_description":"Interested to learn about Secure Service? Check our article explaining how to use HTTPS and OAuth 2.0 to secure service-to-service communication.","og_url":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2019-03-18T06:55:04+00:00","article_modified_time":"2019-03-25T06:44:35+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Matt Raible","twitter_card":"summary_large_image","twitter_creator":"@mraible","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Matt Raible","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/03\/secure-service-spring-microservices.html"},"author":{"name":"Matt Raible","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/54edd49deb980d7706e2af51514c3f7f"},"headline":"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0","datePublished":"2019-03-18T06:55:04+00:00","dateModified":"2019-03-25T06:44:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/03\/secure-service-spring-microservices.html"},"wordCount":2162,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Microservices","OAuth","Spring","Spring Boot","Spring Cloud"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2019\/03\/secure-service-spring-microservices.html","url":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2","name":"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0 - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#primaryimage"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2019-03-18T06:55:04+00:00","dateModified":"2019-03-25T06:44:35+00:00","description":"Interested to learn about Secure Service? Check our article explaining how to use HTTPS and OAuth 2.0 to secure service-to-service communication.","breadcrumb":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/developer.okta.com\/blog\/2019\/03\/07\/spring-microservices-https-oauth2#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Secure Service-to-Service Spring Microservices with HTTPS and OAuth 2.0"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/54edd49deb980d7706e2af51514c3f7f","name":"Matt Raible","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g","caption":"Matt Raible"},"description":"Java Champion and Developer Advocate @okta with a passion for skiing, mtn biking, VWs, &amp; good beer.","sameAs":["https:\/\/developer.okta.com","https:\/\/x.com\/mraible"],"url":"https:\/\/www.javacodegeeks.com\/author\/matt-raible"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/89400","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/13127"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=89400"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/89400\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=89400"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=89400"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=89400"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}