Outdated 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 matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstalliTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To secure a Spring Boot REST API with JWT bearer tokens, configure it as an OAuth 2.0 resource server: add Spring Security’s resource-server and JOSE support, trust the token issuer and signing keys, then define which routes and authorities are allowed. This guide uses Spring Boot 3.5 and the compatible Spring Security 6.5 line, with tokens issued by an external authorization server—not minted by the API.
What this example secures
The API below exposes a public health check and protects its business endpoints. A valid bearer token must pass JWT validation before a protected request reaches its controller. Route rules then determine whether the authenticated caller has the required scope. Authentication answers who presented a valid token; authorization answers whether that caller may perform a particular operation.
The examples use Spring Boot 3.5, Spring Security 6.5, Java configuration, and the servlet stack. Spring Security’s current reference identifies 7.1.1 as stable, but the cited references do not provide a full compatibility matrix. Keep Spring Boot and Spring Security versions aligned through the Spring Boot dependency management for your selected Boot release rather than overriding security modules individually. The configuration concepts are similar in newer releases, but check the documentation for the versions in your project.
Free tools Windows power users keep installed
One-click scans. No signup required.
This API is a resource server, not an authorization server. An external identity provider or authorization server authenticates users and issues access tokens. Spring Security’s OAuth2 overview distinguishes resource-server support from authorization-server functionality; its JWT support includes a decoder and encoder API, but no token-issuing endpoint. See Spring Security’s OAuth2 overview.
#1 Best Overall
1. Add JWT resource-server dependencies
For a Spring Boot Maven project, include the resource-server starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
Spring Security requires both OAuth2 Resource Server support and JOSE support for JWT decoding and verification. The Boot starter supplies the relevant modules through Boot’s dependency management; avoid selecting independent versions unless you have a specific reason and have checked compatibility. Gradle projects should use the equivalent Spring Boot-managed starter dependency.
Spring Security’s reference puts the setup succinctly: “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.” The practical details—validation rules and endpoint policy—still need to be made explicit. See Spring Security’s JWT resource-server reference.
2. Add a REST endpoint
A small controller makes the public-versus-protected distinction clear. The health route is intended for basic availability checks; the API route returns data only after authentication and authorization succeed.
Rank #2
@RestController
@RequestMapping("/api")
public class MessageController {
@GetMapping("/health")
public Map<String, String> health() {
return Map.of("status", "ok");
}
@GetMapping("/messages")
public Map<String, String> messages() {
return Map.of("message", "You have access to the messages API.");
}
@PostMapping("/messages")
public Map<String, String> createMessage() {
return Map.of("result", "Message created");
}
}
The controller does not itself check JWT claims. Spring Security’s filter chain applies the route policy before requests reach the protected methods.
3. Configure the trusted issuer
Get the issuer URI from the authorization server’s configuration. It must correspond to the JWT’s iss claim and the provider’s metadata. Do not copy the example hostname as a working identity provider:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://idp.example.com/issuer
With issuer-based configuration, Spring Security uses supported provider metadata to discover the public keys needed to verify signatures and configures issuer validation. When using Boot, the property is spring.security.oauth2.resourceserver.jwt.issuer-uri. Provider discovery support and URI formats vary, so confirm the exact issuer value and metadata support with the selected provider. The official references describe this configuration in the JWT resource-server guide and the Spring Boot 3.5 security reference.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use a direct JWK Set URI when discovery is unsuitable
If metadata discovery is unavailable or you do not want startup to depend on contacting the authorization server for discovery, specify the provider’s JWK Set URI directly. Keeping issuer-uri preserves issuer validation:
Rank #3
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://idp.example.com
jwk-set-uri: https://idp.example.com/.well-known/jwks.json
The JWK endpoint is provider-specific; use its documented value rather than assuming this example path. A JWK Set can provide updated verification keys as signing keys rotate, but your deployment still depends on the endpoint’s availability and the framework’s key-refresh behavior.
Use a PEM public key only when that fits key operations
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 public key can suit a tightly managed deployment, but you must plan how the API receives and replaces the key when the issuer rotates signing keys. Never put a private signing key in the API’s source code or distribute it as if it were a verification key.
Boot’s supported JWT settings, including issuer-uri, jwk-set-uri, audiences, and public-key-location, are documented in its Spring Security reference.
4. Define public and protected routes
The following servlet security configuration leaves only /api/health public, requires the messages.read scope to read messages, and requires messages.write to create them. Spring Security maps OAuth scopes to authorities prefixed with SCOPE_ by default, so the authorization rules correspond to SCOPE_messages.read and SCOPE_messages.write.
Rank #4
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api/health").permitAll()
.requestMatchers(HttpMethod.GET, "/api/messages")
.hasAuthority("SCOPE_messages.read")
.requestMatchers(HttpMethod.POST, "/api/messages")
.hasAuthority("SCOPE_messages.write")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.build();
}
}
Add imports for the Spring Security configuration and HTTP method types used in the class, including HttpMethod, Customizer, and SecurityFilterChain. The final anyRequest().authenticated() prevents any route not explicitly made public from being anonymous. Replace or extend the scope rules to match the actual claims issued for your application; a rule for a scope absent from the token will deny access, even when the token is otherwise valid.
This is an example for a servlet application. Reactive WebFlux applications use the corresponding reactive security configuration rather than SecurityFilterChain. Spring Security’s servlet JWT reference and the reactive JWT reference describe their respective APIs.
5. What happens to a bearer-token request
- The client sends an access token in the HTTP header
Authorization: Bearer <access-token>. - Spring Security’s bearer-token processing extracts the token and passes authentication through its security machinery.
JwtAuthenticationProviderdelegates decoding, signature verification, and validation to aJwtDecoder.- After validation succeeds,
JwtAuthenticationConverterconverts token claims—such as scopes—into granted authorities. - The authorization rules check those authorities before allowing the request to reach the controller.
This separation matters: a correctly signed token is not automatically allowed to call every API operation. Spring Security documents this flow in its 6.5 JWT resource-server reference.
6. Know what the API validates
JWT signature verification proves that the token was signed by a key the API trusts; it does not establish that the token was issued for this API or grants a requested permission. Check the claims and policy relevant to your provider and application:
- Signature: verify it with trusted provider keys or the configured public key. Do not accept tokens signed with an algorithm or key outside your trust policy.
- Issuer: validate that
issmatches the trusted issuer configured for the API. - Time validity: reject tokens that have expired (
exp) or are not yet valid (nbf). - Audience: if the API requires tokens targeted specifically to it, validate the expected
audvalue. Spring Boot documents thespring.security.oauth2.resourceserver.jwt.audiencesproperty; configure the value your authorization server actually emits. - Authorization claims: ensure required scopes or other authorities are present and mapped to the rules protecting each operation.
Issuer and time validators are part of the standard resource-server JWT configuration described by Spring Security. Audience expectations are application- and provider-specific; do not assume signature validation alone enforces the audience your API needs.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.7. Check the expected outcomes
| Request condition | Expected result | Reason |
|---|---|---|
GET /api/health, no token |
Allowed | The route is explicitly public. |
GET /api/messages, no bearer token |
401 Unauthorized | The route requires an authenticated request. |
Protected route with a valid token containing messages.read |
Allowed for GET | The token validates and maps to SCOPE_messages.read. |
| Protected route with an expired or not-yet-valid token | 401 Unauthorized | Token time validation fails. |
| Protected route with a token from the wrong issuer or an untrusted signing key | 401 Unauthorized | The token does not satisfy trust and validation requirements. |
POST /api/messages, valid token lacking messages.write |
403 Forbidden | Authentication can succeed while authorization fails. |
These are the expected outcomes of the configured policy, not a report of a test run. If your application customizes exception handling, responses may differ in format while preserving the same authentication-versus-authorization distinction.
8. Choose the token validation approach that fits
| Approach | When it fits | Operational consideration |
|---|---|---|
| Issuer discovery | The authorization server publishes supported metadata and you want the API to discover its signing keys. | Startup or configuration relies on provider metadata being reachable for discovery. |
| Direct JWK Set URI | You need to configure the key-set location directly or avoid metadata discovery at startup. | The configured URI must be the provider’s actual JWK endpoint; retain issuer validation when issuer checking is required. |
| PEM public key | The deployment uses a fixed public key and does not have a usable JWK endpoint. | Key rotation and deployment of replacement public keys become your operational responsibility. |
| Opaque bearer-token introspection | The authorization server issues opaque tokens or the API should ask it to validate tokens through introspection. | This is a different resource-server mode, using OpaqueTokenIntrospector rather than local JWT decoding. |
Spring Boot documents both JWT and opaque-token resource-server configuration, while Spring Security’s OAuth2 overview explains the separate support paths. See Boot’s security configuration reference and Spring Security’s OAuth2 overview.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsQuick Recap
9. Production checks before deployment
- Confirm that the configured issuer exactly matches the issuer in tokens from the chosen authorization server.
- Decide whether the API must enforce a particular audience and configure the expected value accordingly.
- Check the signing algorithms and trusted keys accepted by your provider and API; do not broaden trust to make invalid tokens pass.
- Plan for key rotation and verify that the JWK endpoint or public-key distribution process will deliver new verification keys to the API.
- Keep credentials and any private signing material out of source code. A resource server generally needs verification keys, not the issuer’s private signing key.
- Review every route’s authorization requirement. Do not mistake successful token decoding for the complete business access policy.
- Ensure the identity provider’s metadata and key endpoints are reachable as required by your chosen configuration and runtime behavior.
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.

