Return to site

🔐🛡️ JWT RESOURCE SERVER IN SPRING BOOT: VERIFY, CONVERT, AUTHORIZE

· spring

JWT security in Spring Boot is powerful… but only when we separate responsibilities clearly. A Resource Server is not “the place where users log in”. It is the API that receives access tokens, validates them, extracts identity/permissions, and decides what the caller can access. ✅

🔸 TL;DR

Spring Boot can secure APIs as OAuth2 Resource Servers by validating JWTs, mapping claims to authorities, and applying authorization rules per endpoint.

🔸 1. PROTECTING AN API WITH TOKENS

A Resource Server is the backend API that protects business resources. It trusts an Authorization Server to issue tokens, then verifies incoming JWTs before processing requests.

GET /api/orders
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...

The API does not authenticate the user with a password. It receives a Bearer token, validates it, then decides whether the request is allowed.

🔸 2. TURNING SPRING BOOT INTO A RESOURCE SERVER

Spring Security can validate JWTs automatically when the issuer or JWK Set URI is configured. Your API becomes responsible for checking token validity on each protected request.

☝️ A JWK Set URI is the URL where a Resource Server can fetch the public keys used to verify JWT signatures. (yaml property jwk-set-uri that can be used in place of issuer-uri)

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth.example.com/realms/demo

@Bean
SecurityFilterChain security(HttpSecurity http) throws Exception {
    return http
        .authorizeHttpRequests(auth -> auth
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer(oauth2 -> oauth2.jwt())
        .build();
}

Spring Boot uses the issuer metadata to validate JWT signature, expiration, and issuer. Every request must be authenticated unless you explicitly allow it.

🔸 3. ADAPTING JWT CLAIMS TO SPRING AUTHORITIES

JWTs often contain roles or permissions in custom claims. A converter lets you translate those claims into Spring Security authorities used by authorization rules.

☝️ hasRole - A shortcut for hasAuthority that prefixes ROLE_ or whatever is configured as the default prefix: https://docs.spring.io/spring-security/reference/servlet/authorization/authorize-http-requests.html

@Bean
JwtAuthenticationConverter jwtAuthenticationConverter() {
    var authorities = new JwtGrantedAuthoritiesConverter();
    authorities.setAuthoritiesClaimName("roles");
    authorities.setAuthorityPrefix("ROLE_");

    var converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(authorities);

    return converter;
}

This maps a JWT claim like "roles": ["ADMIN"] to ROLE_ADMIN, making it usable with rules like hasRole("ADMIN").

🔸 4. SECURING ENDPOINTS BY INTENT

Once JWTs are validated and claims are mapped, endpoint rules define what each caller can do. Keep rules explicit, readable, and aligned with business intent.

@Bean
SecurityFilterChain security(
        HttpSecurity http,
        JwtAuthenticationConverter converter
) throws Exception {
    return http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/public/**").permitAll()
            .requestMatchers("/admin/**").hasRole("ADMIN")                     
            .requestMatchers("/orders/**")
                        .hasAuthority("SCOPE_orders:read")
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer(oauth2 -> oauth2
            .jwt(jwt -> jwt.jwtAuthenticationConverter(converter))
        )
        .build();
}

Public routes stay open, admin routes require a role, and order routes require a scope. The token is verified first, then authorization rules are applied.

🔸 TAKEAWAYS

▪️ A Resource Server protects APIs; it does not issue JWTs.

▪️ JWT validation should be handled by Spring Security, not custom manual parsing.

▪️ Claims are not automatically “business permissions”; sometimes they must be converted.

▪️ Authorization rules should express business access clearly.

▪️ Security config is not just technical plumbing — it documents who can do what.

JWTs are not magic. They become useful when validation, claim mapping, and authorization rules are designed together. 🔐

#Java #SpringBoot #SpringSecurity #OAuth2 #JWT #BackendDevelopment #APISecurity #SoftwareEngineering #CleanCode #JavaDeveloper

Go further with Java certification:

Java👇

Spring👇

SpringBook👇

JavaBook👇