Back to Repositories

Testing OAuth2 Authorization Controls in spring-boot-demo

This test suite validates OAuth2 authorization functionality in a Spring Boot resource server, covering role-based access control (RBAC) and scope-based authorization. The tests verify different user roles and access scopes for various endpoints.

Test Coverage Overview

The test suite provides comprehensive coverage of OAuth2 authorization mechanisms:
  • Role-based access testing for ROLE_ADMIN and ROLE_TEST
  • Scope-based authorization testing for READ and WRITE operations
  • Access denial verification for unauthorized roles and scopes
  • Combined scope testing for multi-permission scenarios

Implementation Analysis

The testing approach utilizes JUnit 5 with OAuth2RestTemplate for authorization testing:
  • Isolated test methods with @DisplayName annotations for clear test purposes
  • OAuth2RestTemplate configuration for different user credentials and scopes
  • HTTP response validation for both successful and denied access scenarios
  • Exception handling verification for unauthorized access attempts

Technical Details

Testing infrastructure includes:
  • JUnit Jupiter test framework
  • Spring Security OAuth2 client
  • OAuth2RestTemplate for authenticated requests
  • Local test server running on port 8081
  • Custom AuthorizationTest base class for common OAuth2 setup

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Clear test method naming conventions
  • Systematic coverage of positive and negative test cases
  • Proper separation of concerns for different authorization scenarios
  • Efficient test setup using inheritance and helper methods
  • Comprehensive assertion checking for both success and failure cases

xkcoding/spring-boot-demo

demo-oauth/oauth-resource-server/src/test/java/com/xkcoding/oauth/controller/TestControllerTest.java

            
package com.xkcoding.oauth.controller;

import com.xkcoding.oauth.AuthorizationTest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;

import java.util.Arrays;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.http.HttpMethod.GET;

/**
 * .
 *
 * @author <a href="https://echocow.cn">EchoCow</a>
 * @date 2020-01-09  15:46
 */
public class TestControllerTest extends AuthorizationTest {

    private static final String URL = "http://127.0.0.1:8081";

    @Test
    @DisplayName("ROLE_ADMIN 角色测试")
    void testAdminRoleSucceedAndTestRoleFailedWhenPassed() {
        OAuth2RestTemplate template = oauth2RestTemplate("admin", "123456", Collections.singletonList("READ"));
        ResponseEntity<String> response = template.exchange(URL + "/admin", GET, null, String.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("ADMIN", response.getBody());
        assertThrows(OAuth2AccessDeniedException.class, () -> template.exchange(URL + "/test", GET, null, String.class));
    }

    @Test
    @DisplayName("ROLE_Test 角色测试")
    void testTestRoleSucceedWhenPassed() {
        OAuth2RestTemplate template = oauth2RestTemplate("test", "123456", Collections.singletonList("READ"));
        ResponseEntity<String> response = template.exchange(URL + "/test", GET, null, String.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("TEST", response.getBody());
        assertThrows(OAuth2AccessDeniedException.class, () -> template.exchange(URL + "/admin", GET, null, String.class));
    }

    @Test
    @DisplayName("SCOPE_READ 授权域测试")
    void testScopeReadWhenPassed() {
        OAuth2RestTemplate template = oauth2RestTemplate("admin", "123456", Collections.singletonList("READ"));
        ResponseEntity<String> response = template.exchange(URL + "/read", GET, null, String.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("READ", response.getBody());
        assertThrows(OAuth2AccessDeniedException.class, () -> template.exchange(URL + "/write", GET, null, String.class));
    }

    @Test
    @DisplayName("SCOPE_WRITE 授权域测试")
    void testScopeWriteWhenPassed() {
        OAuth2RestTemplate template = oauth2RestTemplate("admin", "123456", Collections.singletonList("WRITE"));
        ResponseEntity<String> response = template.exchange(URL + "/write", GET, null, String.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("WRITE", response.getBody());
        assertThrows(OAuth2AccessDeniedException.class, () -> template.exchange(URL + "/read", GET, null, String.class));
    }

    @Test
    @DisplayName("SCOPE 测试")
    void testScopeWhenPassed() {
        OAuth2RestTemplate template = oauth2RestTemplate("admin", "123456", Arrays.asList("READ", "WRITE"));
        ResponseEntity<String> writeResponse = template.exchange(URL + "/write", GET, null, String.class);
        assertEquals(HttpStatus.OK, writeResponse.getStatusCode());
        assertEquals("WRITE", writeResponse.getBody());
        ResponseEntity<String> readResponse = template.exchange(URL + "/read", GET, null, String.class);
        assertEquals(HttpStatus.OK, readResponse.getStatusCode());
        assertEquals("READ", readResponse.getBody());
    }
}