CodeGym /Courses /Module 5. Spring /Lecture 109: Protecting resources with OAuth2

Lecture 109: Protecting resources with OAuth2

Module 5. Spring
Level 18 , Lesson 8
Available

Every application, whether it's a huge online store or a small note-taking service, has resources that need protection: user data, sensitive information, or operations that change the system state. Our job as developers is to make those resources available only to people who are supposed to have access.

Without proper protection anyone with basic tools (yes, we're looking at Postman) can hit your API, and we definitely don't want that.

OAuth2 gives us a great tool to manage access: tokens. Today we'll go over how to set up your Spring Boot project to enforce strict resource protection.


Security components for resources

Before diving into the practical part, let's quickly define the key components you'll need to protect resources with OAuth2:

  1. Resource Server:
    • The component that serves protected data and verifies tokens before granting access. This is usually where your REST APIs live.
  2. Access Token:
    • A special token the client uses to knock on the Resource Server's door. The token carries info like what actions are allowed and for which user.
  3. Roles and permissions:
    • Access control via roles (for example, ROLE_USER, ROLE_ADMIN) and scopes, which define what a user can do.
  4. Spring Security:
    • The framework that handles access checks to resources, token validation, and security policy configuration.

Implementing resource protection in Spring Boot

Let's get practical. We'll configure a Spring Boot app to act as a Resource Server, using OAuth2 and JWT.

Project setup

Make sure you have the following dependencies in your pom.xml (or build.gradle):


<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-security</artifactId>
</dependency>

These dependencies add Resource Server support and Spring Security.


Resource server configuration

1. Security filters configuration

Create a configuration class for Spring Security:


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll() // Public resources
                .antMatchers("/admin/**").hasRole("ADMIN") // Admins only
                .antMatchers("/user/**").hasRole("USER") // Users only
                .anyRequest().authenticated() // Everything else requires authentication
            .and()
            .oauth2ResourceServer()
                .jwt(); // Use JWT to validate tokens
    }
}

Here we define:

  • Which endpoints are public.
  • Which resources require specific roles.
  • Configuring the OAuth2 Resource Server to use JWT.

2. JWT token configuration

Add the following to application.yml (or application.properties) to tell Spring where to find the public key to verify JWT signatures:


spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth-server.example.com/realms/myrealm
# Here should be the URL of your authorization server (Issuer URI)

The issuer-uri property tells Spring Security where the authorization server is (for example, Keycloak or Auth0) so it can fetch token configuration.


Example of a protected controller

Let's create a REST controller that demonstrates using roles and scopes.


@RestController
@RequestMapping("/api")
public class ResourceController {

    @GetMapping("/public")
    public String publicEndpoint() {
        return "This is a public resource, available to everyone!";
    }

    @GetMapping("/user/hello")
    public String userEndpoint(@AuthenticationPrincipal Jwt jwt) {
        return "Hello, user " + jwt.getClaimAsString("preferred_username") + "!";
    }

    @GetMapping("/admin/dashboard")
    public String adminEndpoint() {
        return "This is an administrative resource. Welcome, mighty Admin!";
    }
}
  • The /public endpoint is available to everyone.
  • The /user/hello endpoint requires the USER role and prints information from the JWT (for example, preferred_username).
  • The /admin/dashboard endpoint is available only to administrators.

How to test the server?

  • Step 1: get a JWT. Do this from your authorization server (for example, Keycloak or Auth0).
  • Step 2: send a request with the header Authorization: Bearer <your token> to protected endpoints.
  • Step 3: verify that access is granted or denied depending on role and scope.

Managing roles and permissions

Roles in OAuth2 and JWT play a key role in granting access to resources. For example, ROLE_ADMIN grants access to admin resources, while ROLE_USER grants access to user resources.

A JWT can include scopes and roles as additional claims. Example token structure:


{
  "sub": "user123",
  "scope": "read write",
  "roles": ["USER", "ADMIN"],
  "exp": 1698777600
}

How to check roles in Spring? Spring Security will automatically map roles in the token into authorities. You can use annotations:

@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/secure/admin")
public String securedAdminEndpoint() {
    return "Admins only!";
}


Common errors and fixes

  1. "403 Forbidden" even with a valid token — most likely your roles or scopes are misconfigured. Make sure the roles in the token match what your app expects.
  2. JWT signature verification error — usually means your Resource Server couldn't fetch the public key from the authorization server. Check the issuer-uri and ensure the authorization server is reachable.
  3. Expired token — make sure your clients use Refresh tokens to renew access tokens.

Real-world usage

Using OAuth2 and JWT to protect resources provides robust and scalable security for microservice architectures. This pattern is used in many real projects, from enterprise apps to social authentication platforms.

Next time you visit a site and see a "Sign in with Google" button, you'll know OAuth2 is at work.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION