Resource Server in Spring Boot

A Resource Server is an application that serves protected resources and validates access tokens issued by an Authorization Server (like Keycloak, Okta, Auth0, or a custom Authorization Server).


🔑 Core Concepts

  1. Authorization Server → Issues tokens (JWT, opaque). Example: Keycloak, Auth0.
  2. Resource Server → Your Spring Boot REST API that checks tokens before serving data.
  3. Client → A frontend/mobile app that requests tokens from Authorization Server and calls the Resource Server.

🚀 Example: Spring Boot Resource Server

We’ll build a simple REST API (/api/hello) protected with JWT validation.

1. Dependencies (pom.xml)

Add Spring Boot starter + security + OAuth2 resource server:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-jose</artifactId>
    </dependency>
</dependencies>

2. Configuration (application.yml)

Here, we assume JWT tokens are issued by an Authorization Server (example: Keycloak):

server:
  port: 8081

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth-server.com/realms/myrealm
  • issuer-uri → The endpoint where the Resource Server can fetch public keys (JWKS) to validate tokens.
  • Works with Keycloak, Okta, Auth0, etc.

3. Security Config (SecurityConfig.java)

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@org.springframework.context.annotation.Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2.jwt()); // enable JWT validation

        return http.build();
    }
}

4. REST Controller (HelloController.java)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;

@RestController
public class HelloController {

    @GetMapping("/api/public")
    public String publicEndpoint() {
        return "This is a public endpoint 🚀";
    }

    @GetMapping("/api/hello")
    public String hello(@AuthenticationPrincipal Jwt jwt) {
        return "Hello, " + jwt.getClaim("preferred_username");
    }
}

5. Running & Testing

  • Run your Spring Boot app (mvn spring-boot:run).
  • Get a valid JWT token from your Authorization Server.
  • Call your endpoint with token:
curl -H "Authorization: Bearer <access_token>" http://localhost:8081/api/hello

If the token is valid → ✅ returns "Hello, <username>".
If not → ❌ returns 401 Unauthorized.


🏁 Summary

  • You used Spring Security + Resource Server to protect APIs.
  • Configured it to validate JWT tokens from an external Authorization Server.
  • Created public and protected endpoints.

Leave a Reply