A complete demonstration of Spring Security OAuth2 Authorization Server with resource server and client applications. This multi-module Maven project showcases the implementation of OAuth2 authorization code flow, JWT token generation, and secure resource access patterns.
- Overview
- Architecture
- Project Structure
- Prerequisites
- Getting Started
- Configuration
- Testing the Flow
- Endpoints
- Technology Stack
This project demonstrates a complete OAuth2/OpenID Connect implementation using Spring Security's authorization server. It includes:
- ✅ OAuth2 Authorization Server - Issues JWT access tokens
- ✅ Resource Server - Protects API resources with JWT validation
- ✅ Client Application - Consumes protected resources via OAuth2
- ✅ User Management - H2 database with JPA entities
- ✅ Multiple Grant Types - Authorization Code, Password, Refresh Token
- ✅ RSA JWT Signing - Secure token generation with key pairs
┌─────────────┐ ┌─────────────────────┐ ┌──────────────────┐
│ Client │────────▶│ Authorization Server│◀────────│ Resource Server │
│ (Port 8080) │ │ (Port 9000) │ │ (Port 9001) │
└─────────────┘ └─────────────────────┘ └──────────────────┘
│ │ │
│ 1. Request authorization │ │
│──────────────────────────▶│ │
│ │ │
│ 2. User login & consent │ │
│◀──────────────────────────│ │
│ │ │
│ 3. Authorization code │ │
│◀──────────────────────────│ │
│ │ │
│ 4. Exchange for token │ │
│──────────────────────────▶│ │
│ │ │
│ 5. Access token (JWT) │ │
│◀──────────────────────────│ │
│ │
│ 6. Access resource with token │
│─────────────────────────────────────────────────────────▶│
│ │
│ 7. Validate JWT & return resource │
│◀─────────────────────────────────────────────────────────│
target-case-study/
├── model/ # Shared domain model
│ └── src/main/java/
│ └── com/casestudy/db/
│ ├── entity/
│ │ └── CaseStudyUser.java # User entity with JPA annotations
│ └── repository/
│ └── UserRepository.java # Spring Data JPA repository
│
├── auth-server/ # OAuth2 Authorization Server
│ ├── src/main/java/
│ │ └── com/casestudy/security/auth/server/
│ │ ├── config/
│ │ │ ├── AuthServerConfig.java # OAuth2 server configuration
│ │ │ └── SecurityConfig.java # Security filter chain
│ │ └── service/
│ │ ├── CaseStudyAuthServerAuthenticationProvider.java
│ │ └── CaseStudyUserDetailsService.java
│ └── src/main/resources/
│ ├── application.yml # Server runs on port 9000
│ └── data.sql # Sample user data
│
├── resource-server/ # Protected API Resources
│ ├── src/main/java/
│ │ └── com/casestudy/security/resource/server/
│ │ ├── config/
│ │ │ └── SecurityConfig.java # JWT validation config
│ │ └── controller/
│ │ └── ResouceController.java # Protected endpoints
│ └── src/main/resources/
│ └── application.yml # Server runs on port 9001
│
├── client/ # OAuth2 Client Application
│ ├── src/main/java/
│ │ └── com/casestudy/client/
│ │ ├── config/
│ │ │ └── SecurityConfig.java # OAuth2 client config
│ │ └── controller/
│ │ └── HelloController.java # Client endpoints
│ └── src/main/resources/
│ └── application.yml # Server runs on port 8080
│
└── pom.xml # Parent POM
- Java: 17 or higher
- Maven: 3.8+
- Git: For cloning the repository
git clone git@github.com:anishk835/target-case-study.git
cd target-case-studyThe authorization server uses auth-server as the issuer hostname. Add this to your hosts file:
macOS/Linux:
sudo nano /etc/hostsWindows:
notepad C:\Windows\System32\drivers\etc\hostsAdd the following line:
127.0.0.1 auth-server
mvn clean installOpen three separate terminal windows:
Terminal 1: Authorization Server
cd auth-server
mvn spring-boot:run✅ Runs on http://auth-server:9000
Terminal 2: Resource Server
cd resource-server
mvn spring-boot:run✅ Runs on http://localhost:9001
Terminal 3: Client Application
cd client
mvn spring-boot:run✅ Runs on http://localhost:8080
OAuth2 Client Registration:
- Client ID:
api-client - Client Secret:
secret - Grant Types: Authorization Code, Password, Refresh Token
- Scopes:
openid,api.read - Redirect URIs:
http://127.0.0.1:8080/authorizedhttp://127.0.0.1:8080/login/oauth2/code/api-client-oicd
Database (H2 In-Memory):
- Console:
http://auth-server:9000/h2-console - JDBC URL:
jdbc:h2:mem:db - Username:
sa - Password:
sa
Users are loaded from auth-server/src/main/resources/data.sql:
| Username | Password | Role |
|---|---|---|
| user1 | password1 | USER |
| user2 | password2 | USER |
-
Initiate Authorization: Open your browser and navigate to:
http://localhost:8080/oauth2/authorization/api-client-authorization-code -
Login:
- Username:
user1 - Password:
password1
- Username:
-
Grant Consent:
- Approve the requested scopes (
api.read)
- Approve the requested scopes (
-
Access Protected Resource:
http://localhost:8080/api/hello
1. Get Authorization Code (Browser Required):
Navigate to:
http://auth-server:9000/oauth2/authorize?response_type=code&client_id=api-client&scope=api.read&redirect_uri=http://127.0.0.1:8080/authorized
After login and consent, you'll be redirected to:
http://127.0.0.1:8080/authorized?code=AUTHORIZATION_CODE
2. Exchange Code for Access Token:
curl -X POST http://auth-server:9000/oauth2/token \
-u api-client:secret \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=http://127.0.0.1:8080/authorized"3. Access Protected Resource:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
http://localhost:9001/api/resources| Endpoint | Method | Description |
|---|---|---|
/oauth2/authorize |
GET | Authorization endpoint |
/oauth2/token |
POST | Token endpoint |
/oauth2/jwks |
GET | JSON Web Key Set |
/.well-known/oauth-authorization-server |
GET | OAuth2 metadata |
/h2-console |
GET | H2 database console |
| Endpoint | Method | Auth Required | Description |
|---|---|---|---|
/api/resources |
GET | ✅ JWT Token | Protected resource endpoint |
| Endpoint | Method | Auth Required | Description |
|---|---|---|---|
/hello |
GET | ❌ Public | Public endpoint |
/api/hello |
GET | ✅ OAuth2 Login | Protected endpoint |
/authorized |
GET | - | OAuth2 redirect URI |
- Spring Boot: 2.7.4
- Spring Security: OAuth2 Authorization Server
- Java: 17
- Spring Security OAuth2 Authorization Server: 0.3.1
- Spring Security OAuth2 Resource Server: JWT validation
- Spring Security OAuth2 Client: OAuth2 login
- Spring Data JPA: Database abstraction
- H2 Database: In-memory database
- Hibernate: ORM
- Lombok: Reduce boilerplate code
- Nimbus JOSE+JWT: JWT and JWK handling
The project includes a custom CaseStudyAuthServerAuthenticationProvider that authenticates users against a JPA-backed user repository.
Uses RSA-based JWT signing with dynamically generated key pairs (2048-bit).
Clean separation of concerns with shared model module and independent server applications.
Debug and inspect user data via the H2 web console during development.
Users must explicitly approve requested scopes before token issuance.
mvn testmvn clean package -DskipTests- Navigate to:
http://auth-server:9000/h2-console - Use connection details:
- JDBC URL:
jdbc:h2:mem:db - Username:
sa - Password:
sa
- JDBC URL:
Contributions are welcome! Please feel free to submit a Pull Request.
This project is created for educational and case study purposes.
Anish Kumar
- GitHub: @anishk835
Solution: Ensure auth-server is added to your /etc/hosts file pointing to 127.0.0.1
Solution: Make sure the authorization server is running and listening on port 9000
Solution: Verify the redirect URI in the client configuration matches the registered URI in AuthServerConfig.java
⭐ If you find this project helpful, please give it a star!