Securing Spring Boot API With API Key and Secret
Last Updated :
24 May, 2024
In Web applications, securing the APIs is critical. One of the common methods of securing the APIs is by using API keys and secrets. This ensures that only the authorized clients can access the API endpoints. This article can guide you through the process of securing the Spring Boot API using the API keys and secrets.
Securing the Spring Boot API with an API key and Secret can involve authenticating and authorizing the incoming requests to ensure only valid clients can access the API endpoints. This concept primarily revolves around intercepting HTTP requests and extracting the API key and secret, validating them. It can allow or deny access based on the validity of the application.
1. Authentication and Authorization
- Authentication is the process of verifying the identity of the client. In this case, it can involve checking the provided API key and secret.
- Authorization is the process of checking whether the authenticated client has permission to access the specific resource.
2.API Key and Secret
The API Key is a unique identifier used to the authenticate the client making a request. The API Secret is a private key can be used in conjunction with the API Key to the add the extra layer of the security. Both are typically provided in the request headers.
3.Custom Authentication token
To handle the API Key and secret authentication, We need a custom authentication token that can extends the Abstract Authentication Token. This token will hold the API Key and secret and manage the authentication state of the application.
4.Custom Authentication Filter
The Custom filter can be need to intercept the HTTP requests and extract the API key and secret from the header. This filter will attempt to the authenticate the request by the creating an instance of API Key Authentication Token and passing it to the authentication manager.
5.Security Configuration
The Spring Security configuration sets up the custom authentication filter and defines the security rules for the API endpoints. The filter can added to the security filter chain to the process requests to /api/** endpoints.
6.Endpoint Implementation
Finally, we can develop the API endpoint is defined in the controller that can demonstrates the secured endpoint.
Implementation to Secure Spring Boot API With API Key and Secret
We can develop the simple spring boot application that can demonstrates the securing spring boot API key and secret of the application.
Step 1: Create the Spring project.
Create a new Spring Boot project using Spring Initializr and add the required dependencies,
- Spring Web
- Spring Security
- Lombok
- Spring DevTools
After the creation of the project has done, the folder structure will be like below image.

Step 2: Configure the Application properties
Open application.properties file and add the configuration for the server port in the project.
spring.application.name=spring-boot-secure-API
server.port=8081
Step 3: Create the ApiKeyAuthenticationToken class
This class can handles the API Key and Secret authentication and this token will holds the API Key and secret and manage the authentication state.
Go to src > main > java > org.example.springbootsecureapi > config > ApiKeyAuthenticationToken and put the below code.
Java
package org.example.springbootsecureapi.config;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
public class ApiKeyAuthenticationToken extends AbstractAuthenticationToken {
private final String apiKey;
private final String apiSecret;
public ApiKeyAuthenticationToken(String apiKey, String apiSecret) {
super(null);
this.apiKey = apiKey;
this.apiSecret = apiSecret;
setAuthenticated(false);
}
public ApiKeyAuthenticationToken(String apiKey, String apiSecret, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.apiKey = apiKey;
this.apiSecret = apiSecret;
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return this.apiSecret;
}
@Override
public Object getPrincipal() {
return this.apiKey;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
}
}
Step 4: Create the ApiKeyAuthFilter class
This filter class will attempt to the authenticate the request by creating an instance of ApiKeyAuthenticationToken and passing it to authentication manager.
Go to src > main > java > org.example.springbootsecureapi > config > ApiKeyAuthFilter and put the below code.
Java
package org.example.springbootsecureapi.config;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import java.io.IOException;
public class ApiKeyAuthFilter extends AbstractAuthenticationProcessingFilter {
private static final String API_KEY_HEADER = "API-Key";
private static final String API_SECRET_HEADER = "API-Secret";
public ApiKeyAuthFilter(RequestMatcher requiresAuth) {
super(requiresAuth);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException {
String apiKey = request.getHeader(API_KEY_HEADER);
String apiSecret = request.getHeader(API_SECRET_HEADER);
if (apiKey == null || apiSecret == null) {
throw new RuntimeException("Missing API Key or Secret");
}
Authentication auth = new ApiKeyAuthenticationToken(apiKey, apiSecret);
return getAuthenticationManager().authenticate(auth);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
chain.doFilter(request, response);
}
}
Step 5: Create the SecurityConfig class
This SecurityConfig class can sets up the custom authentication filter and defines the security rules for the API endpoints.
Go to src > main > java > org.example.springbootsecureapi > config > SecurityConfig and put the below code.
Java
package org.example.springbootsecureapi.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.util.Collections;
import java.util.Collections;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
ApiKeyAuthFilter filter = new ApiKeyAuthFilter(new AntPathRequestMatcher("/api/**"));
filter.setAuthenticationManager(authentication -> {
String apiKey = (String) authentication.getPrincipal();
String apiSecret = (String) authentication.getCredentials();
if ("valid-api-key".equals(apiKey) && "valid-api-secret".equals(apiSecret)) {
return new ApiKeyAuthenticationToken(apiKey, apiSecret, Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")));
} else {
authentication.setAuthenticated(false);
}
return authentication;
});
http
.csrf().disable()
.authorizeRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/api/**").authenticated()
.anyRequest().permitAll()
)
.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Step 6: Create the ApiController class
Go to src > main > java > org.example.springbootsecureapi > controller > ApiController and put the below code.
Java
package org.example.springbootsecureapi.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/data")
public String getSecureData() {
return "This is Spring Boot API secured data!";
}
}
Step 7: Main Class
Main class will be as it is, we do not need to change anything.
Java
package org.example.springbootsecureapi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootSecureApiApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSecureApiApplication.class, args);
}
}
pom.xml:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>spring-boot-secure-API</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-secure-API</name>
<description>spring-boot-secure-API</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 8: Run the application
Once, we run the application, it will start at port 8081.

Step 9: Endpoint Testing
1. Endpoint without the api key and secret
GET http://localhost:8081/api/data
Then show the error like below:
Missing API Key and secret
Output:

2. Endpoint Test with API key and secret
GET http://localhost:8081/api/data
Add the API key and secret in Header section.
API Key : valid-api-key
API Secret: valid-api-key
Output:

By the following these steps, we can secure the Spring Boot API using API keys and secrets. This method ensures that only the clients with valid credentials can access the API endpoints and thereby adding the extra layer of the security to the Spring Boot application.
Similar Reads
Securing Spring Boot 3 Applications With SSL Bundles In a web environment, securing an application is a crucial necessity. SSL, a Secure Socket Layer, provides a secure channel between the client and server by encrypting the transmitted data. In this article, we will go through the steps to secure a Spring Boot 3 application using SSL Bundles.What is
5 min read
How to Build a RESTful API with Spring Boot and Spring MVC? RESTful APIs have become the standard for building scalable and maintainable web services in web development. REST (Representational State Transfer) enables a stateless, client-server architecture where resources are accessed via standard HTTP methods. This article demonstrates how to create a RESTf
7 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
Spring Security Integration with Spring Boot Spring Security is a powerful and customizable authentication and access control framework for Java applications. It provides comprehensive security services for Java EE-based enterprise software applications. This article will integrate Spring Security with a Spring Boot application, covering confi
5 min read
How to Integrate Keycloak with Spring Boot and Spring Security? Keycloak is Open Source Identity and Access Management (IAM) solution developed by Red Hat. By using this you can add authentication to applications and secure services with minimum effort. No need to deal with storing users or authenticating users. Keycloak provides user federation, strong authenti
2 min read
Securing API Keys Using Android NDK As Android developers, we create Android apps and rely on a variety of third-party libraries (SDK tools) because we can't do everything ourselves. It's possible that you'll have to use Google Maps or other Google Play services. Because the majority of these services are paid, securing the API keys o
11 min read
Secure Service Registration with Eureka and Spring Boot Microservices In microservice architecture, service registration and discovery can plays the crucial role. Eureka is a part of the Spring Cloud Netflix project and it provides the mechanism to register and discover the services. It ensure the secure communication between the services. It is important to secure th
4 min read
How to Create a Simple Spring Boot Application? Spring Boot is one of the most popular frameworks for building Java-based web applications. It is used because it simplifies the development process by providing default configurations and also reduces boilerplate code. In this article, we will cover the steps to create a simple Spring Boot applicat
2 min read
Easiest Way to Create REST API using Spring Boot Spring Boot is a powerful framework that makes it easy to create RESTful APIs. Creating a REST API using Spring Boot is one of the fastest and simplest ways to develop scalable and production-ready web services. Spring Boot simplifies REST API development by providing built-in features such as autom
10 min read
Securing Spring Cloud Config Server with Basic Authentication Spring Cloud Config Server provides externalization for distributed systems. With the increasing importance of microservices, centrally managing configurations becomes crucial. Securing this configuration server is equally important to prevent unauthorized access. Basic authentication is a simple an
4 min read