Spring Boot: From Basics to Production · Securing APIs with Spring Security

JWT Resource Server with OAuth2/OIDC

Validate access tokens from an identity provider.

Most APIs shouldn't issue their own tokens; they act as an OAuth2 resource server that validates JWTs issued by an identity provider (Keycloak, Auth0, Okta, Cognito, Entra ID). Set the issuer URI and Spring fetches the JWKS, validates signature, expiry and issuer. Add audience validation and map claims (roles/scopes) to authorities with a JwtAuthenticationConverter.

@Bean
JwtDecoder jwtDecoder(@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}") String issuer) {
    NimbusJwtDecoder decoder = JwtDecoders.fromIssuerLocation(issuer);
    OAuth2TokenValidator<Jwt> audience = jwt -> jwt.getAudience().contains("shop-api")
            ? OAuth2TokenValidatorResult.success()
            : OAuth2TokenValidatorResult.failure(new OAuth2Error("invalid_token", "Wrong audience", null));
    decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(JwtValidators.createDefaultWithIssuer(issuer), audience));
    return decoder;
}

@Bean
JwtAuthenticationConverter jwtAuthenticationConverter() {
    var authorities = new JwtGrantedAuthoritiesConverter();
    authorities.setAuthoritiesClaimName("roles");
    authorities.setAuthorityPrefix("ROLE_");
    var converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(authorities);
    return converter;
}
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth.example.com/realms/shop

Common pitfalls

  • Skipping audience validation (tokens for other APIs are accepted).
  • Building your own JWT parsing instead of using the resource server support.
  • Putting fine-grained permissions in long-lived tokens.

Key points

  • Validate IdP-issued JWTs
  • Check issuer, expiry and audience
  • Map claims to authorities

Further reading: Spring Security: JWT resource server

Practice questions

Why validate the aud claim?

Answer

Without it, a valid token issued by the same IdP for another API would be accepted by yours (token confusion).

How does the resource server get the IdP's public keys?

Answer

From the issuer's OpenID configuration and JWKS endpoint, cached and refreshed for key rotation.

Open in the app to mark lessons complete, take notes and track your progress.