Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Build

on:
push:
branches: [ main, master, develop, nginx-ssl ]
pull_request:
branches: [ main, master, develop ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'gradle'

- name: Build SAS
working-directory: ./hello-sample-sas
run: |
chmod +x ./gradlew
./gradlew build --no-daemon

- name: Build APP (API)
working-directory: ./hello-sample-app
run: |
chmod +x ./gradlew
./gradlew build --no-daemon

- name: Upload build artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
hello-sample-sas/build/libs/*.jar
hello-sample-app/build/libs/*.jar
retention-days: 7

75 changes: 75 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Summary of Changes - Swagger UI OAuth2 Redirect URI Configuration

## Changes Made

### 1. Environment Variables (.env)
- Added `SAS_SERVER_EXTERNAL=https://localhost/auth` for browser-facing OAuth2 redirects
- Updated `APP_SERVER=https://localhost/api` to use external URL
- Kept `SAS_SERVER=http://sas:9000/auth` for internal service-to-service JWT validation

### 2. Nginx Configuration (nginx/nginx.conf)
- Added `X-Forwarded-Host` header to both `/auth/` and `/api/` locations
- Added `X-Forwarded-Port 443` header to both locations
- These headers help Spring construct correct redirect URLs when behind a reverse proxy

### 3. Application Configuration (hello-sample-app/src/main/resources/application.yml)
- Confirmed `forward-headers-strategy: framework` is enabled (allows Spring to use X-Forwarded headers)
- Updated `oauth.issuer-url` to use `${SAS_SERVER_EXTERNAL}` for browser redirects
- Updated `oAuthFlow.authorizationUrl` to use `${SAS_SERVER_EXTERNAL}/oauth2/authorize`
- Updated `oAuthFlow.tokenUrl` to use `${SAS_SERVER_EXTERNAL}/oauth2/token`
- Updated CORS `allowed-origins` to use `${SAS_SERVER_EXTERNAL}` instead of `${SAS_SERVER}`
- JWT validation still uses `${SAS_SERVER}` (internal URL) for jwk-set-uri and issuer-uri

### 4. Authorization Server Configuration (hello-sample-sas/src/main/resources/application.yml)
- Confirmed `forward-headers-strategy: framework` is enabled
- Confirmed redirect-uris uses `${APP_SERVER}` which now points to external URL
- Updated CORS `allowed-origins` to use `${SAS_SERVER_EXTERNAL}` instead of `${SAS_SERVER}`

## Why These Changes Were Necessary

### The Problem
In Docker Compose with nginx reverse proxy:
- Services communicate internally using HTTP (e.g., `http://sas:9000/auth`)
- Browser accesses services through HTTPS nginx (e.g., `https://localhost/auth`)
- Swagger UI OAuth2 redirects must use the external URL that the browser can access
- JWT validation should use internal URL for better performance and reliability

### The Solution
**Separate Internal and External URLs:**
- `SAS_SERVER` (internal): For service-to-service communication (JWT validation)
- `SAS_SERVER_EXTERNAL` (external): For browser-facing OAuth2 flows
- `APP_SERVER` (external): For browser redirects back to Swagger UI

**Enable Proxy Header Support:**
- Spring Boot's `forward-headers-strategy: framework` makes it aware of proxy
- Nginx's `X-Forwarded-*` headers tell Spring the original request details
- This ensures Spring generates correct redirect URLs even when behind a proxy

## How OAuth2 Flow Works Now

1. **User opens Swagger UI**: `https://localhost/api/swagger-ui`
2. **Click Authorize**: Browser redirects to `https://localhost/auth/oauth2/authorize`
3. **User authenticates**: Via GitHub IDP
4. **Authorization server redirects back**: `https://localhost/api/swagger-ui/oauth2-redirect.html`
5. **Swagger UI exchanges code for token**: POST to `https://localhost/auth/oauth2/token`
6. **Token validation (backend)**: App validates token by calling `http://sas:9000/auth/oauth2/jwks`

## Testing

To test the configuration:

```bash
# Rebuild and start services
docker-compose down
docker-compose up --build

# Access Swagger UI
open https://localhost/api/swagger-ui

# Click "Authorize" button and complete OAuth2 flow
```

## Documentation

See [SWAGGER-OAUTH2-SETUP.md](./SWAGGER-OAUTH2-SETUP.md) for detailed explanation of the configuration.

9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
# DOCKER COMPOSE COMMANDS

up:
@docker compose --project-name hello-spring-auth up --build --detach
@docker compose up --build --detach

down:
@docker compose --project-name hello-spring-auth down
@docker compose down

downv:
@docker compose --project-name hello-spring-auth down --remove-orphans -v
@docker compose down --remove-orphans -v

logs:
@docker compose logs -f

restart-nginx:
@docker compose restart nginx


# BASH ACCESS

Expand Down
84 changes: 84 additions & 0 deletions QUICK-REFERENCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Swagger UI OAuth2 - Quick Reference

## URLs

### Browser Access (External)
- **Swagger UI**: https://localhost/api/swagger-ui
- **Authorization Server**: https://localhost/auth
- **API**: https://localhost/api

### Internal Service Communication
- **JWT Validation**: http://sas:9000/auth

## Key Configuration Points

### ✅ What's Configured

1. **Redirect URI**: `https://localhost/api/swagger-ui/oauth2-redirect.html`
- Configured in Swagger UI (app)
- Registered in OAuth2 client (sas)

2. **OAuth2 Endpoints**:
- Authorization: `https://localhost/auth/oauth2/authorize`
- Token: `https://localhost/auth/oauth2/token`
- JWKS: `http://sas:9000/auth/oauth2/jwks` (internal)

3. **PKCE**: Enabled (`use-pkce-with-authorization-code-grant: true`)

4. **Scopes**: `openid`, `api.read`

5. **Proxy Headers**: Enabled via `forward-headers-strategy: framework`

## Environment Variables

```bash
# Internal (service-to-service)
SAS_SERVER=http://sas:9000/auth

# External (browser-facing)
SAS_SERVER_EXTERNAL=https://localhost/auth
APP_SERVER=https://localhost/api
```

## Quick Start

```bash
# Start services
docker-compose up --build

# Access Swagger UI
open https://localhost/api/swagger-ui

# Test OAuth2 flow
1. Click "Authorize" button
2. Login with GitHub
3. Allow access
4. You should be redirected back to Swagger UI with access token
```

## Troubleshooting

| Issue | Check |
|-------|-------|
| Redirect URI mismatch | Verify `APP_SERVER` in `.env` |
| CORS errors | Check `allowed-origins` uses external URLs |
| JWT validation fails | Verify `SAS_SERVER` uses internal URL |
| Wrong redirect URL | Check `forward-headers-strategy: framework` is set |
| SSL warnings | Accept self-signed certificate in browser |

## Architecture

```
┌─────────┐ HTTPS ┌───────┐
│ Browser │ ──────────────────────▶│ Nginx │
└─────────┘ https://localhost └───────┘
┌──────────────────┴──────────────────┐
│ │
HTTP HTTP
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ SAS │◀───── JWT Validate ────│ App │
│ :9000 │ (internal) │ :8080 │
└───────────┘ └───────────┘
```
Loading