To secure a Spring Boot REST API with JWT bearer tokens, configure it as an OAuth2 Resource Server, provide a trusted issuer or signing-key source, and define authorization rules for each route. This guide uses Spring Boot 3.5 and the Spring Security 6.5 line, with tokens issued by an external authorization server. It does not build a token issuer: login and token creation belong to that separate system.
The examples use Java configuration and a servlet-based API. Spring Security 7.1.1 is identified as the current stable reference version, but this guide does not assert that it is a drop-in pair with Spring Boot 3.5. Check compatibility before changing versions.
As an Amazon Associate I earn from qualifying purchases.
1. Understand what the API is doing
A resource server receives access tokens and decides whether to allow requests. In this design, the authorization server authenticates users or clients and issues JWTs; the Spring Boot API validates each presented token and applies its own route policy.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsSpring Security’s reference documentation summarizes the Boot setup this way: “When using Spring Boot, configuring an application as a resource server consists of two basic steps. First, include the needed dependencies. Second, indicate the location of the authorization server.” Those steps enable token processing, but they do not decide which authenticated callers may perform each business operation.
#1 Best Overall
JWT bearer authentication is appropriate when the API can validate signed tokens from a trusted issuer. If the provider instead issues opaque bearer tokens, Spring Security supports an introspection-based resource-server configuration; that is a different validation flow.
2. Add the resource-server dependencies
For a Maven project managed by Spring Boot, add the OAuth2 resource-server starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
JWT bearer support needs both Spring Security’s OAuth2 Resource Server support and JOSE support for decoding and verifying JWTs. Spring Boot’s starter is the convenient dependency entry point; if managing Spring Security modules directly, ensure the resource-server and JOSE modules are both present. Do not mix independently selected Spring Boot and Spring Security versions without checking their compatibility.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
3. Create one public route and protected API routes
For a small example, expose a health route publicly and keep the rest of the API authenticated. The controller can be ordinary Spring MVC code:
@RestController
@RequestMapping("/api")
class ApiController {
@GetMapping("/health")
Map<String, String> health() {
return Map.of("status", "ok");
}
@GetMapping("/reports")
List<String> reports() {
return List.of("monthly-summary");
}
}
The intended policy in this example is precise: GET /api/health is public; GET /api/reports requires a valid bearer token with the reports.read scope. In a real application, make the route list and the required scopes match its actual business operations.
4. Configure how JWTs are trusted
Issuer discovery
When the authorization server exposes supported metadata, configure its exact issuer URI in application.yml:
Rank #3
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://idp.example.com/issuer
Replace the example with the issuer URI supplied by the identity provider. It must correspond to the token’s iss claim. With issuer-based configuration, Spring Security can use provider configuration and public-key discovery to obtain keys and validate issuer information. See the Spring Security JWT resource-server reference.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Direct JWK Set URI
If provider metadata is unavailable, or application startup should not depend on metadata discovery, configure the provider’s JWK Set endpoint directly. Keep the issuer configured when issuer validation is required:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://idp.example.com
jwk-set-uri: https://idp.example.com/.well-known/jwks.json
The JWK URL is provider-specific; do not assume the illustrative path is universal. Directly configuring it avoids the metadata lookup at startup described in the Spring Security reference, while retaining issuer-uri for issuer validation.
Rank #4
Pinned public key
Spring Boot also documents public-key-location for a PEM-encoded X.509 public key when a JWK Set URI is not available. A pinned key can fit deployments with deliberate key-management procedures, but it does not provide a provider’s rotating key set automatically. Plan how key changes reach every API instance before relying on it. See the Spring Boot 3.5 Spring Security configuration reference.
Validate audience when the API requires it
Issuer validation answers which authority issued a token; audience validation checks whether the token was intended for this API. If your provider places an API audience in access tokens and your security policy requires it, configure the expected audience, for example:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchspring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://idp.example.com/issuer
audiences:
- reports-api
Use the actual audience value expected by the provider and API, not this illustrative value. Spring Boot documents the audiences property; verify its behavior against the selected Boot version.
5. Define route authorization explicitly
A servlet security chain can permit the health route, require the reports.read scope for reports, and require authentication for everything else:
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(HttpMethod.GET, "/api/health").permitAll()
.requestMatchers(HttpMethod.GET, "/api/reports")
.hasAuthority("SCOPE_reports.read")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.build();
}
}
Include the imports appropriate to your project, including HttpMethod, Customizer, and Spring Security configuration types. Spring Security maps scope claims to authorities prefixed with SCOPE_ by default, which is why the rule uses SCOPE_reports.read. If your authorization server issues different scope names or claim structures, adapt the mapping and rules rather than assuming the example scope exists.
.anyRequest().authenticated() makes all routes not explicitly permitted or given a stricter rule require authentication. It does not mean every authenticated user is authorized for every operation; the reports route additionally requires its scope. The official servlet reference shows the underlying SecurityFilterChain and JWT resource-server setup: Spring Security OAuth2 resource-server configuration.
6. Follow a bearer token through the security pipeline
- The client sends an access token in the request’s
Authorization: Bearer …header. - Spring Security’s bearer-token handling passes the credential into its authentication machinery.
JwtAuthenticationProvidercalls aJwtDecoderto decode the JWT, verify its signature, and validate relevant claims such as issuer and time validity.- A
JwtAuthenticationConverterturns the validated JWT’s claims into granted authorities. Scope values map toSCOPE_-prefixed authorities by default. - The configured authorization rules decide whether the authenticated request has the authority needed for its route.
These are separate decisions: successful signature verification does not establish that a token is meant for this API, nor that its bearer may perform every action. Configure and test the issuer, expiration and not-before handling, audience where needed, trusted signing algorithms, and authorization policy. Spring Security describes this flow in its servlet JWT resource-server documentation.
7. Check the expected request outcomes
| Request condition | Expected result | Why |
|---|---|---|
GET /api/health, no token |
Allowed by this example’s route policy | The health route is explicitly public. |
GET /api/reports, no bearer token |
Rejected as unauthenticated | The route requires an authenticated caller. |
GET /api/reports, valid token with reports.read |
Authorized by the configured rule | The default scope mapping supplies SCOPE_reports.read. |
GET /api/reports, valid token without that scope |
Rejected as forbidden | Authentication succeeded, but the required authority is absent. |
| Protected route, expired or not-yet-valid token | Rejected during token validation | The token is outside its validity period. |
| Protected route, token with the wrong issuer | Rejected during token validation | The token does not match the configured trusted issuer. |
These outcomes follow the example’s configuration; they are not claims of an independently executed test. Exact error response details can depend on the application’s exception handling and Spring Security configuration.
8. Check deployment details before relying on the setup
- Confirm that the configured issuer matches the provider’s metadata and the JWT
issclaim. - Decide whether an audience check is required for this API and ensure issued access tokens contain the expected audience.
- Trust only signing algorithms and keys appropriate to the provider and deployment; understand how JWK rotation is surfaced and consumed.
- Keep private signing keys out of the API and its public source code. A resource server needs trusted verification material, not the issuer’s private key.
- Check that provider metadata and JWK endpoints are reachable as required by your chosen configuration, especially during application startup and key rotation.
- Ensure endpoint authorities correspond to scopes actually issued for the API; add a custom converter only when the provider’s claim format requires one.
- If the application is reactive rather than servlet-based, use the reactive security chain and matching APIs instead of copying the servlet
SecurityFilterChainexample.
Spring Security separates resource-server, client, and authorization-server capabilities. It provides a JwtEncoder interface and Nimbus implementation, but does not provide a token-minting endpoint simply by enabling resource-server support. Token issuance therefore remains the responsibility of an external authorization server or a separately designed issuer. See the Spring Security OAuth2 overview.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →




