Spring Security API key authentication for REST APIs tutorial — Complete Guide
A practical, in-depth guide to Spring Security API key authentication for REST APIs tutorial with examples.
INTRO
Every day we ship micro‑services that expose JSON endpoints to internal tools, mobile apps, or third‑party partners. The default Spring Security setup assumes a session‑based, form‑login flow—perfect for web UIs but a poor fit for stateless APIs. When you try to protect a REST endpoint with the out‑of‑the‑box configuration, you quickly hit a wall: CSRF tokens, redirects, and HttpSession objects start leaking into your API contract, forcing clients to handle cookies they never asked for.
The pragmatic solution is to replace the heavyweight OAuth dance or JWT boilerplate with a simple API key. An API key is just a secret string that a client includes in each request, typically via a header. It’s easy to generate, rotate, and audit, and it works flawlessly with Spring’s filter chain. The challenge isn’t the concept—it’s wiring the key check into Spring Security without breaking the rest of your configuration, handling missing or malformed keys gracefully, and keeping the implementation testable.
If you’ve ever written a custom OncePerRequestFilter that felt like a hack, or you’ve been forced to expose your endpoints without any protection because “security is too hard,” this guide will show you a clean, production‑ready way to integrate API key authentication directly into Spring Security’s authentication manager.
WHAT YOU'LL LEARN
- How to define a lightweight
AuthenticationTokenthat represents an API key and plug it into Spring’sAuthenticationProvider. - Configuring the security filter chain to intercept requests, extract the key from a custom header, and delegate to the provider.
- Storing API keys securely using Spring Data JPA, with hashing and rotation strategies.
- Writing unit and integration tests for the filter, provider, and controller layers without starting a full server.
- Common pitfalls such as leaking keys in logs, handling multiple keys per client, and mixing API key auth with other mechanisms.
- Production hardening tips: rate limiting, revocation, and monitoring key usage with Spring Actuator.
A SHORT CODE SNIPPET
// 1. Simple Authentication token that holds the raw API key
public class ApiKeyAuthenticationToken extends AbstractAuthenticationToken {
private final String apiKey;
private final UserDetails principal;
public ApiKeyAuthenticationToken(String apiKey) {
super(null);
this.apiKey = apiKey;
this.principal = null;
setAuthenticated(false);
}
public ApiKeyAuthenticationToken(UserDetails principal, String apiKey,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.apiKey = apiKey;
this.principal = principal;
setAuthenticated(true);
}
@Override
public Object getCredentials() {
return apiKey;
}
@Override
public Object getPrincipal() {
return principal;
}
}
This token is the cornerstone of the authentication flow. The filter extracts the header, creates an unauthenticated instance, and hands it to the provider. If the key matches a stored record, the provider returns an authenticated token populated with the user’s authorities.
KEY TAKEAWAYS
-
Leverage Spring’s extensibility: By creating a custom
AuthenticationTokenandAuthenticationProvider, you keep the API key logic out of controllers and let Spring handle the heavy lifting. - Never store raw keys: Hash the API key (e.g., BCrypt) before persisting, and compare hashes during authentication to mitigate leakage.
-
Fail fast and stay silent: Return
401 Unauthorizedwithout revealing whether the key was missing or invalid; this prevents enumeration attacks. - Make it testable: Isolate the filter, provider, and repository so you can unit‑test each piece with mock requests and verify behavior under edge cases.
👉 Read the complete guide with step-by-step examples, common mistakes, and production tips:
Spring Security API key authentication for REST APIs tutorial — Complete Guide
Top comments (0)