Implementing API Key Authentication in Spring Security for REST APIs
This tutorial explains how to secure a Spring Boot REST API using API key authentication, covering the addition of Maven dependencies, creating a custom filter, extending AbstractAuthenticationToken, configuring the security filter chain, and testing the protected endpoint with curl commands.
Security is crucial for REST APIs; an insecure API can expose sensitive data. This guide shows how to protect a Spring Boot REST API using API‑key authentication with Spring Security.
1. Overview
API keys are tokens that clients provide when calling an API, allowing authentication without a user context.
2. REST API Security
Spring Security can protect REST APIs using Basic authentication, OAuth2, JWT, or API keys. Because REST APIs are stateless, API‑key authentication is a lightweight option.
3. Implement API Key Protection
3.1 Add Maven Dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>3.2 Create Custom Filter
public class AuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
try {
Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception exp) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
PrintWriter writer = httpResponse.getWriter();
writer.print(exp.getMessage());
writer.flush();
writer.close();
}
filterChain.doFilter(request, response);
}
}3.3 Authentication Service
public class AuthenticationService {
private static final String AUTH_TOKEN_HEADER_NAME = "X-API-KEY";
private static final String AUTH_TOKEN = "Baeldung";
public static Authentication getAuthentication(HttpServletRequest request) {
String apiKey = request.getHeader(AUTH_TOKEN_HEADER_NAME);
if (apiKey == null || !apiKey.equals(AUTH_TOKEN)) {
throw new BadCredentialsException("Invalid API Key");
}
return new ApiKeyAuthentication(apiKey, AuthorityUtils.NO_AUTHORITIES);
}
}3.4 ApiKeyAuthentication Token
public class ApiKeyAuthentication extends AbstractAuthenticationToken {
private final String apiKey;
public ApiKeyAuthentication(String apiKey, Collection
authorities) {
super(authorities);
this.apiKey = apiKey;
setAuthenticated(true);
}
@Override
public Object getCredentials() { return null; }
@Override
public Object getPrincipal() { return apiKey; }
}3.5 Security Configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/**").authenticated()
.and()
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(new AuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}3.6 Resource Controller
@RestController
public class ResourceController {
@GetMapping("/home")
public String homeEndpoint() {
return "Baeldung !";
}
}4. Testing
Without providing an API key, the request returns a 401 Unauthorized error.
curl --location --request GET 'http://localhost:8080/home'When the valid API key is added to the request header, the endpoint returns 200 OK.
curl --location --request GET 'http://localhost:8080/home' \
--header 'X-API-KEY: Baeldung'Source: Baeldung tutorial on Spring Boot API‑key authentication.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.