Spring Cloud - Securing Services
Last Updated :
28 Apr, 2025
Spring Cloud Security is an extremely versatile and strong framework for access control and authentication. To secure the Spring-based applications, this is a good mechanism. A Java application's authentication and authorization are the main goals of the Spring Security framework. Our application can be authenticated across the board by using Spring Cloud Gateway and Spring Session to log users into a single service. This indicates that it will be simple for us to divide our application into appropriate domains and protect each one as needed.
Step-by-Step Implementation Spring Cloud – Securing Services
Below are the steps to implement Spring Cloud – Securing Services
Step 1: Integrate The UAA with Spring Cloud Gateway
The OAuth2 configuration included in the application.yml file of our gateway is the first item to take care of while configuring this functionality.
security:
oauth2:
client:
registration:
gateway:
provider: uaa
client-id: gateway
client-secret: secret
authorization-grant-type: authorization_code
redirect-uri-template: "{baseUrl}/login/oauth2/code/{registrationId}"
scope: openid,profile,email,resource.read
provider:
uaa:
authorization-uri: http://localhost:8090/uaa/oauth/authorize
token-uri: http://uaa:8099/uaa/oauth/token
user-info-uri: http://uaa:8099/uaa/userinfo
user-name-attribute: sub
jwk-set-uri: http://uaa:8099/uaa/token_keys
Step 2: Add the Maven Dependency
First, let's make sure that every system module has the spring-boot-starter-security dependency:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Step 3: Create a SecurityConfig class
To replicate our discovery service, let's construct a SecurityConfig class and this class will contain methods to configure authentication and authorization for the application.
Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;
@EnableWebFluxSecurity
@Configuration
public class SecurityConfig {
/**
* Configure a MapReactiveUserDetailsService with two users: "user" and "admin".
*
* @param passwordEncoder the password encoder
* @return a MapReactiveUserDetailsService with two users
*/
@Bean
public MapReactiveUserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
UserDetails adminUser = User.withUsername("admin")
.password(passwordEncoder.encode("admin"))
.roles("ADMIN")
.build();
return new MapReactiveUserDetailsService(user, adminUser);
}
/**
* Configure a SecurityWebFilterChain with URL authorization.
*
* @param http the ServerHttpSecurity object
* @return a SecurityWebFilterChain object with URL authorization
*/
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange()
.pathMatchers("/api/employees").permitAll()
.pathMatchers("/api/employees/*").authenticated()
.and().formLogin()
.and().logout();
return http.build();
}
}
Step 4: Create an Employee class
To represent employee data, create an employee class.
Employee.java:
Java
public class Employee {
private Long id;
private String firstName;
private String lastName;
private String email;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Step 5: Configure Authentication and Authorization
We need to configure authentication and authorization in our application. We can use the SecurityConfig
class to define our security configuration.
Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* Configuration class for security settings.
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* Configures HTTP security.
*
* @param http the HttpSecurity object to configure
* @throws Exception if an error occurs during configuration
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/public/**").permitAll()
.antMatchers(HttpMethod.POST, "/api/public/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/private/**").hasRole("USER")
.antMatchers(HttpMethod.POST, "/api/private/**").hasRole("ADMIN")
.and().httpBasic();
}
/**
* Creates a PasswordEncoder bean for password encoding.
*
* @return a BCryptPasswordEncoder bean
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Step 6: Create a Controller Class to Handle Employee Requests
To handle employee requests, create a controller class.
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* RestController for handling employee-related requests.
*/
@RestController
@RequestMapping("/api")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* Handles GET requests to "/api/public" for public data.
*
* @return the public data
*/
@GetMapping("/public")
public String getPublicData() {
return employeeService.getPublicData();
}
/**
* Handles GET requests to "/api/private/user" for user data.
*
* @return the user data
*/
@GetMapping("/private/user")
public String getUserData() {
return employeeService.getUserData();
}
/**
* Handles POST requests to "/api/private/admin" for admin data.
*
* @return the admin data
*/
@PostMapping("/private/admin")
public String getAdminData() {
return employeeService.getAdminData();
}
}
Step 7: Add properties to the application.properties file
Add the following properties to the rating service's src/main/resources application.properties file:
spring.cloud.config.username=configUser
spring.cloud.config.password=configPassword
eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/
Step 8: Create a test class
In gateway project, let's first construct a test class and a test method:
Java
public class GatewayApplicationTest
{
@Test
public void testAccess() {
// Add test logic to verify access to the gateway application
// For example, use tools like RestTemplate or WebClient to make HTTP requests
// and assert the expected behavior.
}
}
Step 9: Access unprotected /api/employees Endpoint
Let's add this code snippet to our test method so that we can configure our test and confirm that we can access our unprotected /api/employees resource:
Java
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.web.client.TestRestTemplate;
// Create a new instance of TestRestTemplate to test HTTP requests
TestRestTemplate testRestTemplate = new TestRestTemplate();
// Define the base URL of the API being tested
String testUrl = "http://localhost:8080";
// Send a GET request to the "/api/employees" endpoint
ResponseEntity<String> response = testRestTemplate.getForEntity(testUrl + "/api/employees", String.class);
// Verify that the HTTP status code of the response is OK (200)
Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
// Verify that the response body is not null
Assert.assertNotNull(response.getBody());
Step 10: Access the admin protected resource
Our ability to access the admin-protected resource and log in as the administrator will be verified by the following test:
Admin-Protected /api/employees Endpoint:
Java
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
form.add("username", "admin"); // Add username
form.add("password", "admin"); // Add password
// Send a POST request to the "/login" endpoint with the form data
ResponseEntity<String> response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class);
// Verify that the HTTP status code of the response is OK (200)
Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
// Verify that the response body is not null
Assert.assertNotNull(response.getBody());
By following the above steps, we can secure various services of our Spring Cloud application.
Similar Reads
Spring Cloud Security Spring Cloud Security is part of the Spring Cloud ecosystem that can provide the tools and components to secure the microservices-based applications and it can integrate seamlessly with the Spring Boot and Spring Security to offer features such as authentication, authorization, token management, sec
4 min read
Spring Boot - Cloud Configuration Server In microservices, we have several different services responsible for different functionalities. These services act like smaller application modules, which together form the application. Each of these modules has its own responsibility, based on the business logic of the application being built. Thes
10 min read
Spring Cloud Zookeeper For Spring Boot applications, Zookeeper integrates via autoconfiguration, binding to the Spring Environment, and other Spring programming models. Building massively distributed systems with Zookeeper-based components is made possible with just a few annotations to enable and define common patterns w
4 min read
Securing REST APIs with Spring Security In Spring Boot applications, securing the REST APIs is a critical aspect of developing secure and robust applications. REST APIs are commonly used to expose functionalities to external systems, mobile applications, and web applications. Without proper security measures, these APIs can become targets
8 min read
What is Spring Cloud? There are many reasons to use Spring Framework for example if you want faster development, less configuration, auto-configuration, embedded server, production-ready application, and many more. But apart from that most importantly we have ready-made support for microservices and this ready-made suppo
2 min read
Spring Security Architecture Spring Security framework helps us to secure Java-based web applications. The main task of the Spring Security framework is managing who can access what. It is used to protect our application from common security threats such as CSRF and session fixation attacks. Spring Security makes it simple to s
3 min read