DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Spring Cloud Stream: A Brief Guide
  • Full-Duplex Scalable Client-Server Communication with WebSockets and Spring Boot (Part I)
  • Component Tests for Spring Cloud Microservices

Trending

  • Code Reviews: Building an AI-Powered GitHub Integration
  • Apple and Anthropic Partner on AI-Powered Vibe-Coding Tool – Public Release TBD
  • Building a Real-Time Audio Transcription System With OpenAI’s Realtime API
  • Build a Simple REST API Using Python Flask and SQLite (With Tests)
  1. DZone
  2. Coding
  3. Java
  4. Shared Microservice Configurations Using Spring Cloud Config

Shared Microservice Configurations Using Spring Cloud Config

The microservice architecture pattern enables businesses to distribute functionality between many small applications instead of larger monolithic portions.

By 
Joe Cavazos user avatar
Joe Cavazos
·
Jan. 30, 21 · Opinion
Likes (4)
Comment
Save
Tweet
Share
6.3K Views

Join the DZone community and get the full member experience.

Join For Free

The microservice architecture pattern, which is used widely across tech companies large and small, enables businesses to distribute functionality between many small applications, instead of larger monolithic portions. Each piece has a specifically defined task, along with communications and other services, usually via a REST API channel. The benefits of utilizing a microservice architecture include, but are not limited to: 

  • Simple development and maintenance of applications: developers and teams are able to focus on one application rather than multiple, with the benefit of faster development, and fewer hitches (such as bug and easy to miss errors) in the larger project. 

  • Dependable fault tolerance: with the microservice architecture, a service failure will not crash the entire program or project.

  • Flexibility: With the capability to personalize the language and framework for each project you work on, you also can allocate the appropriate hardware/infrastructure.

One of the most popular frameworks is Spring Boot, which is well adept at creating microservices. In addition, its popularity makes it common with many technical guides and examples online, making it one of the most accessible frameworks.  
With Spring Boot you are able to create as many microservices for your project as you need, however, this can lead to complications in the configuration of the conglomerate of services. Normally, Spring Boot configuration comes with the application, which is common and easy to follow through on smaller monolithic applications. The difficulty comes from trying to connect dozens of services and a hundred plus configuration files, which can be a headache to manage.

Spring Cloud Config to the Rescue!

This is where Spring Cloud Config, a framework integrated with Spring Boot, is useful. A dedicated “config server” is brought online from which each microservice can download its configuration data. This dramatically simplifies the management of many microservices by centralizing their configuration in one location and provides the ability to “live” refresh a microservice’s configuration without redeploying the service. As a bonus, Spring Cloud Config provides out-of-the-box support for storing/reading configuration from Git repositories, giving you a full audit history of changes in one location.

In this tutorial, you will:

  • Create a central configuration server using Spring Boot.
  • Create two separate microservices/applications using Spring Boot, which read their configuration from the server.
  • Secure the applications using OAuth 2.0 and Okta.
  • Demonstrate how to (securely) refresh a service’s configuration without redeploying.

Let’s get started!

Prerequisites: Java 11

Create a Spring Cloud Config Server

First, you will create a Spring Boot application that behaves as the configuration server. This application will provide configuration settings to your microservices.

Click this link or go to start.spring.io and select the following options in your browser:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: 2.4.0

Under Project Metadata, set the values to the following:

  • Group: com.okta.dev
  • Artifact: config-server
  • Name: cloud-config-server
  • Description: Configuration Server
  • Package: com.okta.dev.configserver
  • Packaging: Jar
  • Java: 11

Select the following dependencies:

  • Spring Security
  • Spring Web
  • Config Server

Click Generate to download the project files. Unzip the file and import the project files into your favorite IDE.

Open the project in your IDE and update src/main/resources/application.properties with the following key-value pairs:

Java
 




x


 
1
server.port=8888
2
spring.cloud.config.server.native.search-locations=/path/to/config/folder
3
spring.security.user.name=configUser
4
spring.security.user.password=configPass



The property spring.cloud.config.server.native.search-locations is the location where you store your configuration files. Replace the value with a folder on your filesystem where these files will be saved. For example, file://${user.home}/config.

Normally your configuration files would be stored in a remote location, for example, a GitHub repository or an Amazon S3 bucket. For instructions on how to store your config files in a git repository, see this section in the Spring Cloud Config documentation. To keep this tutorial simple, you will use the “native” filesystem option above.

Open your application’s main class and add the @EnableConfigServer annotation:

Java
 




xxxxxxxxxx
1


 
1
import org.springframework.cloud.config.server.EnableConfigServer;
2

          
3
@EnableConfigServer
4
@SpringBootApplication
5
public class CloudConfigServerApplication { ... }


Create an OpenID Connect Application

Sign up for a free developer account at https://developer.okta.com/signup. This will be used to secure your microservices using OAuth 2.0 and OpenID Connect (OIDC). After signing up, log in to your Okta account at https://your-okta-domain.okta.com.

Click Applications in the top nav menu.


Click Add Application.



Select Web and click Next.



In Application Settings fill in the following values:

  • Name: My Spring Cloud App (or another name of your choosing)
  • Base URIs: http://localhost:8001 and http://localhost:8002
  • Login Redirect URIs: http://localhost:8001/login/oauth2/code/okta and http://localhost:8002/login/oauth2/code/okta
  • Logout Redirect URIs: http://localhost:8001 and http://localhost:8002
  • Group Assignments: Everyone (should be selected by default)
  • Grant type allowed: Authorization Code

Click Done.

Take note of the values for Client ID and Client secret. These will be necessary for securing your microservices with OAuth 2.0.

Configure Security for Your Microservices Architecture

Next, you’ll need to create the configuration files which will be used by your microservices. Create or open the directory specified above for spring.cloud.config.server.native.search-locations and add the following files:

service-one.yml

Java
 




xxxxxxxxxx
1


 
1
server:
2
  port: 8001
3

          
4
okta:
5
  oauth2:
6
    issuer: https://YOUR_DOMAIN.okta.com/oauth2/default
7
    clientId: YOUR_CLIENT_ID
8
    clientSecret: YOUR_CLIENT_SECRET


Java
 




xxxxxxxxxx
1
26


 
1
service-one-profile1.yml
2

          
3
hello:
4
  message: "Service One Profile One"
5
service-one-profile2.yml
6

          
7
hello:
8
  message: "Service One Profile Two"
9
service-two.yml
10

          
11
server:
12
  port: 8002
13

          
14
okta:
15
  oauth2:
16
    issuer: https://YOUR_DOMAIN.okta.com/oauth2/default
17
    clientId: YOUR_CLIENT_ID
18
    clientSecret: YOUR_CLIENT_SECRET
19
service-two-profile1.yml
20

          
21
hello:
22
  message: "Service Two Profile One"
23
service-two-profile2.yml
24

          
25
hello:
26
  message: "Service Two Profile Two"


  • Replace YOUR_DOMAIN with your Okta account’s domain. It should look something like dev-0123456, e.g. https://dev-0123456.okta.com/oauth2/default,
  • Replace YOUR_CLIENT_ID with the value of the Client ID you created earlier.
  • Replace YOUR_CLIENT_SECRET with your app’s Client secret.

Let’s take a moment to discuss the naming convention for the configuration files. The filenames are important and must be in a certain pattern for your microservices to pick them up:

Java
 




xxxxxxxxxx
1


 
1
/{application}/{profile}[/{label}]
2
/{application}-{profile}.yml
3
/{label}/{application}-{profile}.yml
4
/{application}-{profile}.properties
5
/{label}/{application}-{profile}.properties
6

          


Where:

  • {application} is the name of your microservice specified via your microservice’s spring.application.name property. In this case, service-one and service-two.
  • {profile} matches the list of profiles your microservice is running via the spring.profiles.active property. In this case, profile1 and profile2.
  • {label} is an additional descriptor usually corresponding to a version control branch, e.g. dev or stg. It can be manually set via the spring.cloud.config.label property in the microservice’s bootstrap.properties file or set on the command line (-Dspring.cloud.config.label).

In this tutorial, you have two sets of configuration files: one set for Service One (service-one.yml) and one for Service Two (service-two.yml).

Enter your config server’s project directory and run the application:

Java
 




xxxxxxxxxx
1


 
1
cd /path/to/config-server
2
./mvnw spring-boot:run -Dspring-boot.run.profiles=native


The native profile tells the application to server configuration files from the filesystem directory you populated above.

Create Spring Boot Microservice #1

Let’s create the first of your two microservices.

Open the Spring Initializr or click here.

Select the following options:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: 2.4.0

Under Project Metadata fill in the following information:

  • Group: com.okta.dev
  • Artifact: service-one
  • Name: service-one
  • Description: Microservice One
  • Package: com.okta.dev.service-one
  • Packaging: Jar
  • Java: 11

Select the following dependencies:

  • Spring Web
  • Okta
  • Config Client
  • Spring Boot Actuator

Click Generate and import the project files into your favorite IDE.

Open the project in your IDE and update src/main/resources/application.properties with the following key-value pairs:

Java
 




xxxxxxxxxx
1


 
1
spring.application.name=service-one
2
spring.config.import=configserver:
3
spring.cloud.config.uri=http://localhost:8888
4
spring.cloud.config.username=configUser
5
spring.cloud.config.password=configPass


  • spring.application.name is the name of this microservice and must match the {application} parameter in the filename convention described above.
  • spring.cloud.config.uri is the location of the config server currently running.
  • spring.cloud.config.username and spring.cloud.config.password are used by your microservice to authenticate with the config server while retrieving configuration files. The values must match the values of spring.security.user.name and spring.security.user.password defined in your config server’s application.properties.

To secure your microservice using Okta and OAuth 2.0, open your microservice’s main class and add the following configuration class:

Java
 




xxxxxxxxxx
1
12


 
1
@Configuration
2
public static class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
3
    
4
    @Override
5
    public void configure(HttpSecurity http) throws Exception {
6
        http
7
            .authorizeRequests()
8
            .anyRequest().authenticated()
9
            .and()
10
            .oauth2Login();
11
    }
12
}


Next, add a basic REST controller, which will respond with a message defined in your service’s configuration file (hosted on the config server):

Java
 




xxxxxxxxxx
1
12


 
1
@RestController
2
@RequestMapping("/secure")
3
public static class SecureController {
4
    
5
    @Value("${hello.message}")
6
    private String helloMessage;
7

          
8
    @GetMapping
9
    public String secure(Principal principal) {
10
        return helloMessage;
11
    }
12
}


The resulting application class should now look like this:

Java
 




xxxxxxxxxx
1
46


 
1
package com.okta.dev.serviceone;
2

          
3
import org.springframework.beans.factory.annotation.Value;
4
import org.springframework.boot.SpringApplication;
5
import org.springframework.boot.autoconfigure.SpringBootApplication;
6
import org.springframework.cloud.context.config.annotation.RefreshScope;
7
import org.springframework.context.annotation.Configuration;
8
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
10
import org.springframework.web.bind.annotation.GetMapping;
11
import org.springframework.web.bind.annotation.RequestMapping;
12
import org.springframework.web.bind.annotation.RestController;
13
import java.security.Principal;
14

          
15
@SpringBootApplication
16
public class CloudConfigServiceOneApplication {
17

          
18
    public static void main(String[] args) {
19
        SpringApplication.run(CloudConfigServiceOneApplication.class, args);
20
    }
21

          
22
    @Configuration
23
    public static class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
24
        @Override
25
        public void configure(HttpSecurity http) throws Exception {
26
            http
27
                .authorizeRequests()
28
                .anyRequest().authenticated()
29
                .and()
30
                .oauth2Login();
31
        }
32
    }
33

          
34
    @RestController
35
    @RequestMapping("/secure")
36
    public static class SecureController {
37

          
38
        @Value("${hello.message}")
39
        private String helloMessage;
40

          
41
        @GetMapping
42
        public String secure(Principal principal) {
43
            return helloMessage;
44
        }
45
    }
46
}


Enter your config server’s project directory and run the application with profile1 set:

Java
 




xxxxxxxxxx
1


 
1
cd /path/to/service-one
2
./mvnw spring-boot:run -Dspring-boot.run.profiles=profile1


Open a browser and navigate to http://localhost:8001/secure. You should be redirected to Okta for authentication. After successfully authenticating, you should see the following message:

Java
 




xxxxxxxxxx
1


 
1
Service One Profile One


This is the same message defined in the service-one-profile.yml file you created earlier. Neat!

Next, you will switch your microservice’s active profile to profile2 and observe a different message. Stop your application and re-run with profile2 active:

Java
 




xxxxxxxxxx
1


 
1
./mvnw spring-boot:run -Dspring-boot.run.profiles=profile2


Navigate to http://localhost:8001/secure. You should now see the message defined in service-one-profile2.yml:

Java
 




xxxxxxxxxx
1


 
1
Service One Profile Two


Refresh the Configuration in Your Spring Cloud Config Server

Spring Cloud Config provides the ability to “live” reload your service’s configuration without stopping or re-deploying. To demonstrate this, first, stop service-one and add the @RefreshScope annotation to your REST controller:

Java
 




xxxxxxxxxx
1
16


 
1
import org.springframework.cloud.context.config.annotation.RefreshScope;
2
...
3

          
4
@RefreshScope
5
@RestController
6
@RequestMapping("/secure")
7
public static class SecureController {
8

          
9
    @Value("${hello.message}")
10
    private String helloMessage;
11

          
12
    @GetMapping
13
    public String secure(Principal principal) {
14
        return helloMessage;
15
    }
16
}


When this annotation is applied to a Spring component (i.e., a @Component, @Service, @RestController, etc.), the component is re-created when a configuration refresh occurs, in this case giving an updated value for ${hello.message}.

You can refresh an application’s configuration by including the Spring Boot Actuator dependency, exposing the /actuator/refresh endpoint, and sending an empty POST request.

The Spring Boot Actuator has already been included in your microservice’s dependencies. Edit your configuration files to expose the refresh endpoint:

service-one.yml

Java
 




xxxxxxxxxx
1
14


 
1
server:
2
  port: 8001
3

          
4
okta:
5
  oauth2:
6
    issuer: https://YOUR_DOMAIN.okta.com/oauth2/default
7
    clientId: YOUR_CLIENT_ID
8
    clientSecret: YOUR_CLIENT_SECRET
9

          
10
management:
11
  endpoints:
12
    web:
13
      exposure:
14
        include: "refresh"


service-two.yml

Java
 




xxxxxxxxxx
1
14


 
1
server:
2
  port: 8002
3

          
4
okta:
5
  oauth2:
6
    issuer: https://YOUR_DOMAIN.okta.com/oauth2/default
7
    clientId: YOUR_CLIENT_ID
8
    clientSecret: YOUR_CLIENT_SECRET
9

          
10
management:
11
  endpoints:
12
    web:
13
      exposure:
14
        include: "refresh"


Next, add a security class inside your main application class to secure the endpoint with basic authentication:

Java
 




xxxxxxxxxx
1
21


 
1
@Configuration
2
public static class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
3
    @Override
4
    public void configure(HttpSecurity http) throws Exception {
5
        http
6
            .csrf().disable()
7
            .antMatcher("/actuator/*")
8
            .authorizeRequests()
9
            .antMatchers("/actuator/*").authenticated()
10
            .and()
11
            .httpBasic();
12
    }
13

          
14
    @Override
15
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
16
        auth.inMemoryAuthentication()
17
            .withUser("serviceOneUser")
18
            .password("{noop}serviceOnePassword")
19
            .roles("USER");
20
    }
21
}


Almost finished! Since your application is already authenticated with OIDC using Okta, you need to make these two security configuration classes play nicely with each other. Add the @Order annotations to both so ActuatorSecurityConfig takes precedence. This will allow you to refresh the configuration via /actuator/refresh without triggering the OAuth 2.0 flow.

Your application class should now look like this:

Java
 




xxxxxxxxxx
1
75


 
1
package com.okta.dev.serviceone;
2

          
3
import org.springframework.beans.factory.annotation.Value;
4
import org.springframework.boot.SpringApplication;
5
import org.springframework.boot.autoconfigure.SpringBootApplication;
6
import org.springframework.cloud.context.config.annotation.RefreshScope;
7
import org.springframework.context.annotation.Configuration;
8
import org.springframework.core.annotation.Order;
9
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
10
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
12
import org.springframework.web.bind.annotation.GetMapping;
13
import org.springframework.web.bind.annotation.RequestMapping;
14
import org.springframework.web.bind.annotation.RestController;
15

          
16
import javax.servlet.http.HttpServletRequest;
17
import java.security.Principal;
18

          
19
@SpringBootApplication
20
public class CloudConfigServiceOneApplication {
21

          
22
    public static void main(String[] args) {
23
        SpringApplication.run(CloudConfigServiceOneApplication.class, args);
24
    }
25

          
26
    @Order(1)
27
    @Configuration
28
    public static class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
29
        @Override
30
        public void configure(HttpSecurity http) throws Exception {
31
            http
32
                .csrf().disable()
33
                .antMatcher("/actuator/*")
34
                .authorizeRequests()
35
                .antMatchers("/actuator/*").authenticated()
36
                .and()
37
                .httpBasic();
38
        }
39

          
40
        @Override
41
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
42
            auth.inMemoryAuthentication()
43
                .withUser("serviceOneUser")
44
                .password("{noop}serviceOnePassword")
45
                .roles("USER");
46
        }
47
    }
48

          
49
    @Order(2)
50
    @Configuration
51
    public static class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
52
        @Override
53
        public void configure(HttpSecurity http) throws Exception {
54
            http
55
                .authorizeRequests()
56
                .anyRequest().authenticated()
57
                .and()
58
                .oauth2Login();
59
        }
60
    }
61

          
62
    @RefreshScope
63
    @RestController
64
    @RequestMapping("/secure")
65
    public static class SecureController {
66

          
67
        @Value("${hello.message}")
68
        private String helloMessage;
69

          
70
        @GetMapping
71
        public String secure(Principal principal) {
72
            return helloMessage;
73
        }
74
    }
75
}


Start your application using profile1:

Java
 




xxxxxxxxxx
1


 
1
./mvnw spring-boot:run -Dspring-boot.run.profiles=profile1


Navigate to http://localhost:8001/secure and note the message still says Service One Profile One.

Open your configuration file at /path/to/config/folder/service-one-profile1.yml and edit the message:

service-one-profile1.yml

Java
 




xxxxxxxxxx
1


 
1
hello:
2
  message: "Things have changed"


Save the file and refresh the page at http://localhost:8001/secure. Note that the message has not changed yet and still says Service One Profile One. To have your application receive the updated configuration, you must call the /actuator/refresh endpoint:

Java
 




xxxxxxxxxx
1


 
1
curl -u serviceOneUser:serviceOnePassword -X POST http://localhost:8001/actuator/refresh


Refresh the page at http://localhost:8001/secure, and you should see the updated message!

Create Spring Boot Microservice #2

Next, you will create a second Spring Boot application, acting as a second microservice, which will also have its configuration provided by your configuration server.

Open the Spring Initializr or click this link.

Select the following options:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: 2.4.0

Under Project Metadata fill in the following information:

  • Group: com.okta.dev
  • Artifact: service-two
  • Name: service-two
  • Description: Microservice Two
  • Package: com.okta.dev.service-two
  • Packaging: Jar
  • Java: 11

Select the following dependencies (the same list as service-one):

  • Spring Web
  • Okta
  • Config Client
  • Spring Boot Actuator

Click Generate and import the project files into your favorite IDE.

Open the project in your IDE and update src/main/resources/application.properties with the following properties:

Java
 




xxxxxxxxxx
1


 
1
spring.application.name=service-two
2
spring.config.import=configserver:
3
spring.cloud.config.uri=http://localhost:8888
4
spring.cloud.config.username=configUser
5
spring.cloud.config.password=configPass


Note the value for spring.application.name is different.

Make the same changes to your main application class as above:

Java
 




xxxxxxxxxx
1
74


 
1
package com.okta.dev.servicetwo;
2

          
3
import org.springframework.beans.factory.annotation.Value;
4
import org.springframework.boot.SpringApplication;
5
import org.springframework.boot.autoconfigure.SpringBootApplication;
6
import org.springframework.cloud.context.config.annotation.RefreshScope;
7
import org.springframework.context.annotation.Configuration;
8
import org.springframework.core.annotation.Order;
9
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
10
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
12
import org.springframework.web.bind.annotation.GetMapping;
13
import org.springframework.web.bind.annotation.RequestMapping;
14
import org.springframework.web.bind.annotation.RestController;
15

          
16
import java.security.Principal;
17

          
18
@SpringBootApplication
19
public class ServiceTwoApplication {
20

          
21
    public static void main(String[] args) {
22
        SpringApplication.run(ServiceTwoApplication.class, args);
23
    }
24

          
25
    @Order(1)
26
    @Configuration
27
    public static class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
28
        @Override
29
        public void configure(HttpSecurity http) throws Exception {
30
            http
31
                .csrf().disable()
32
                .antMatcher("/actuator/*")
33
                .authorizeRequests()
34
                .antMatchers("/actuator/*").authenticated()
35
                .and()
36
                .httpBasic();
37
        }
38

          
39
        @Override
40
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
41
            auth.inMemoryAuthentication()
42
                .withUser("serviceTwoUser")
43
                .password("{noop}serviceTwoPassword")
44
                .roles("USER");
45
        }
46
    }
47

          
48
    @Order(2)
49
    @Configuration
50
    public static class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
51
        @Override
52
        public void configure(HttpSecurity http) throws Exception {
53
            http
54
                .authorizeRequests()
55
                .anyRequest().authenticated()
56
                .and()
57
                .oauth2Login();
58
        }
59
    }
60

          
61
    @RefreshScope
62
    @RestController
63
    @RequestMapping("/secure")
64
    public static class SecureController {
65

          
66
        @Value("${hello.message}")
67
        private String helloMessage;
68

          
69
        @GetMapping
70
        public String secure(Principal principal) {
71
            return helloMessage;
72
        }
73
    }
74
}


Note the different credentials for the in-memory user: serviceTwoUser / serviceTwoPassword.

Run the application:

Java
 




xxxxxxxxxx
1


 
1
cd /path/to/service-two
2
./mvnw spring-boot:run -Dspring-boot.run.profiles=profile1


Navigate to http://localhost:8002/secure and authenticate with Okta. When you are redirected back to your application you will see the welcome message for service-two:

Java
 




xxxxxxxxxx
1


 
1
Service Two Profile One


You’re done! You’ve created two microservices, secured by Okta and OAuth 2.0, which receive their configuration settings from a shared Spring Cloud Config server. Very cool! 

Learn More About Spring Cloud Config and Microservices

This tutorial showed you how to distribute your security configuration between microservices. There’s a lot more you can do with Spring Cloud Config, like encrypting the values you store, and using it with Spring Vault to store your secrets in a more secure location.

For in-depth examples and use cases not covered in this tutorial, see Spring’s official documentation for Spring Cloud Config.

The source code for this example is on GitHub in the oktadeveloper/okta-spring-cloud-config-example repository.

Check out these other articles on integrating Spring Boot with Okta:

  • Secure Secrets With Spring Cloud Config and Vault
  • A Quick Guide to OAuth 2.0 with Spring Security
  • Easy Single Sign-On with Spring Boot and OAuth 2.0
  • Use PKCE with OAuth 2.0 and Spring Boot for Better Security
  • Spring Security SAML and Database Authentication

Please provide comments, questions, and any feedback in the comments section below.

Follow us on social media (Twitter, Facebook, LinkedIn) to know when we’ve posted more articles like this, and please subscribe to our YouTube channel for tutorials and screencasts!

We’re also streaming on Twitch, follow us to be notified when we’re live.

Spring Framework Spring Cloud microservice application Spring Security Spring Boot Java (programming language)

Published at DZone with permission of Joe Cavazos. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Spring Cloud Stream: A Brief Guide
  • Full-Duplex Scalable Client-Server Communication with WebSockets and Spring Boot (Part I)
  • Component Tests for Spring Cloud Microservices

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!