Skip to content

Commit f46750d

Browse files
Initial commit
0 parents  commit f46750d

92 files changed

Lines changed: 7617 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @auth0/project-dx-sdks-engineer-codeowner

.github/copilot-instructions.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Copilot Instructions for Auth0 Java SDK
2+
3+
## Architecture Overview
4+
5+
Multi-module Gradle project implementing OAuth2/JWT authentication with DPoP support:
6+
7+
- `auth0-api-java`: Java 8 compatible core library (JWT validation, JWKS, DPoP proofs)
8+
- `auth0-springboot-api`: Java 17 Spring Boot auto-configuration and filters
9+
- `auth0-springboot-api-playground`: Working example application with security integration
10+
11+
**Key Design**: Strategy pattern for authentication modes, factory-based client creation, comprehensive JWT validation with Auth0 JWKS integration.
12+
13+
## Core Authentication Pattern
14+
15+
**Main Entry Point**: `AuthClient.from(AuthOptions)` → creates orchestrator with strategy pattern:
16+
17+
```java
18+
// Factory method selects authentication strategy based on DPoP mode
19+
AuthClient client = AuthClient.from(
20+
new AuthOptions.Builder()
21+
.domain("tenant.auth0.com")
22+
.audience("https://api.example.com")
23+
.dpopMode(DPoPMode.ALLOWED) // DISABLED, ALLOWED (default), REQUIRED
24+
.dpopIatOffsetSeconds(300) // DPoP proof time window
25+
.dpopIatLeewaySeconds(60) // DPoP proof time leeway
26+
.build()
27+
);
28+
29+
// Single verification method for all authentication modes
30+
AuthenticationContext context = client.verifyRequest(headers, httpRequestInfo);
31+
```
32+
33+
**Three Authentication Strategies** extending `AbstractAuthentication`:
34+
35+
- `DisabledDPoPAuthentication`: Bearer tokens only
36+
- `AllowedDPoPAuthentication`: Bearer OR DPoP tokens (auto-detects scheme)
37+
- `RequiredDPoPAuthentication`: DPoP tokens only
38+
39+
**Strategy Selection** happens in `AuthClient` constructor based on `dpopMode`.
40+
41+
## JWT Validation & Claims Patterns
42+
43+
**Always use `JWTValidator` convenience methods** - they handle JWKS fetching and validation:
44+
45+
```java
46+
// Scope validation
47+
DecodedJWT jwt = validator.validateTokenWithRequiredScopes(token, "read:users", "write:users");
48+
DecodedJWT jwt = validator.validateTokenWithAnyScope(token, "admin", "user");
49+
50+
// Claim validation
51+
DecodedJWT jwt = validator.validateTokenWithClaimEquals(token, "role", "admin");
52+
DecodedJWT jwt = validator.validateTokenWithClaimIncludes(token, "permissions", "create");
53+
54+
// Manual validation for complex scenarios
55+
DecodedJWT jwt = validator.validateToken(token);
56+
ClaimValidators.checkRequiredScopes(jwt, "admin");
57+
```
58+
59+
**Key Classes**:
60+
61+
- `JWTValidator`: Core JWT validation with JWKS integration (uses Auth0's `jwks-rsa` library)
62+
- `ClaimValidator`: Manual claim validation helpers
63+
- `DPoPProofValidator`: ES256 signature and proof claim validation
64+
- `TokenExtractor`: Extracts Bearer/DPoP tokens from Authorization headers
65+
66+
## Build & Test Workflows
67+
68+
**Module-specific commands** (root gradle builds are disabled):
69+
70+
```bash
71+
# Core library
72+
./gradlew :auth0-api-java:build
73+
./gradlew :auth0-api-java:test
74+
75+
# Spring Boot integration
76+
./gradlew :auth0-springboot-api:build
77+
./gradlew :auth0-springboot-api:test
78+
79+
# Playground/example
80+
./gradlew :auth0-springboot-api-playground:bootRun
81+
```
82+
83+
**Test Patterns**:
84+
85+
- **JUnit versions**: JUnit 4 (auth0-api-java), JUnit 5 (Spring Boot modules)
86+
- **JWT testing**: Mock `JwkProvider`, generate RSA keypairs, use real JWT/JWKS validation
87+
- **DPoP testing**: Generate ES256 keypairs, create valid/invalid DPoP proofs
88+
- **AssertJ**: Preferred assertion library (`assertThat()`, `assertThatThrownBy()`)
89+
90+
**JAR artifacts**: All modules auto-generate sources/javadoc JARs via `withSourcesJar()`/`withJavadocJar()`
91+
92+
## Spring Boot Integration
93+
94+
**Auto-Configuration**: Add dependency, configure properties, inject beans:
95+
96+
```yaml
97+
# application.yml
98+
auth0:
99+
domain: "dev-tenant.us.auth0.com"
100+
audience: "https://api.example.com/v2/"
101+
dpopMode: ALLOWED
102+
dpopIatOffsetSeconds: 300
103+
dpopIatLeewaySeconds: 60
104+
```
105+
106+
```java
107+
// Auto-configured beans available for injection
108+
@Autowired private AuthClient authClient;
109+
@Autowired private AuthOptions authOptions;
110+
@Autowired private Auth0AuthenticationFilter authFilter;
111+
```
112+
113+
**Security Configuration Pattern**:
114+
115+
```java
116+
@Configuration
117+
public class SecurityConfig {
118+
@Bean
119+
SecurityFilterChain apiSecurity(HttpSecurity http, Auth0AuthenticationFilter authFilter) throws Exception {
120+
return http.csrf(csrf -> csrf.disable())
121+
.sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
122+
.authorizeHttpRequests(auth -> auth
123+
.requestMatchers("/api/protected").authenticated()
124+
.anyRequest().permitAll())
125+
.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
126+
.build();
127+
}
128+
}
129+
```
130+
131+
**Classes**: `Auth0AutoConfiguration`, `Auth0Properties`, `Auth0AuthenticationFilter`, `Auth0AuthenticationToken`
132+
133+
## DPoP (Demonstration of Proof-of-Possession) Patterns
134+
135+
**DPoP Mode Behavior**:
136+
137+
- `DISABLED`: Only Bearer tokens accepted
138+
- `ALLOWED` (default): Bearer OR DPoP tokens accepted (auto-detects Authorization scheme)
139+
- `REQUIRED`: Only DPoP tokens accepted
140+
141+
**Critical Validation Rules**:
142+
143+
```java
144+
// ALLOWED mode: Bearer token + DPoP proof header = invalid_request
145+
if (scheme.equals(BEARER) && dpopProofPresent) {
146+
throw new JWTValidationException("Bearer scheme cannot include DPoP proof header");
147+
}
148+
149+
// DPoP bound token (cnf.jkt claim) with Bearer scheme = invalid_token
150+
if (tokenIsDPoPBound && scheme.equals(BEARER)) {
151+
throw new JWTValidationException("DPoP bound token requires DPoP scheme");
152+
}
153+
```
154+
155+
**DPoP Proof Validation**:
156+
157+
- **Header**: `typ: "dpop+jwt"`, `alg: "ES256"`, embedded JWK required
158+
- **Claims**: `htm` (HTTP method), `htu` (HTTP URI), `iat` (issued at with time windows)
159+
- **Token Binding**: Access token's `cnf.jkt` must match DPoP proof JWK thumbprint (RFC 7638)
160+
161+
**WWW-Authenticate Challenges**:
162+
163+
- ALLOWED/DISABLED: `Bearer realm=api; DPoP algs=ES256`
164+
- REQUIRED: `DPoP algs=ES256`
165+
- DPoP errors: `DPoP error=invalid_dpop_proof; error_description="..."`
166+
167+
## Package Structure & Key Classes
168+
169+
**Core (`auth0-api-java/com/auth0/`)**:
170+
171+
- Root: `AuthClient` (main entry), `AbstractAuthentication` (strategy base), authentication strategies
172+
- `validators/`: `JWTValidator`, `DPoPProofValidator`, `ClaimValidator`
173+
- `models/`: `AuthOptions`, `AuthenticationContext`, `HttpRequestInfo`, `AuthToken`
174+
- `exception/`: `BaseAuthException` hierarchy (`InvalidTokenException`, `InsufficientScopeException`, etc.)
175+
- `enums/`: `DPoPMode`, `AuthScheme`
176+
- `examples/`: `Auth0ApiExample` (working HTTP server example)
177+
178+
**Spring Boot (`auth0-springboot-api/com/auth0/spring/boot/`)**:
179+
180+
- `Auth0AutoConfiguration`: Bean definitions and auto-configuration
181+
- `Auth0Properties`: YAML configuration binding (`@ConfigurationProperties`)
182+
- `Auth0AuthenticationFilter`: Spring Security filter integration
183+
- `Auth0AuthenticationToken`: Spring Security authentication token
184+
185+
**Dependencies**:
186+
187+
- Core: `jackson-databind`, `httpclient`, `java-jwt`, `jwks-rsa`
188+
- Spring: `spring-boot-starter-web`, `spring-boot-starter-security`
189+
190+
## Essential Reference Files
191+
192+
- **`JWT_VALIDATION_GUIDE.md`**: Complete JWT validation examples with working code
193+
- **`auth0-api-java/src/main/java/com/auth0/examples/Auth0ApiExample.java`**: HTTP server with authentication
194+
- **`auth0-springboot-api-playground/`**: Full Spring Boot integration example with SecurityConfig
195+
- **Test files**: Comprehensive patterns for mocking JWKS, generating keypairs, testing DPoP proofs
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: auth0/auth0-auth-java/build-and-test
2+
3+
on:
4+
pull_request:
5+
merge_group:
6+
push:
7+
branches: ["master", "main"]
8+
9+
jobs:
10+
gradle:
11+
runs-on: ubuntu-22.04-2cpu-8ram-75ssd
12+
steps:
13+
- uses: actions/checkout@v5
14+
- uses: actions/setup-java@v5
15+
with:
16+
distribution: temurin
17+
java-version: 17
18+
19+
- name: Set up Gradle
20+
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
21+
22+
- name: Test and Assemble with Gradle
23+
run: ./gradlew assemble check --continue --console=plain
24+
25+
- uses: actions/upload-artifact@v4
26+
with:
27+
name: Reports
28+
path: |
29+
packages/auth0-api-java/build/reports/
30+
packages/auth0-springboot-api/build/reports/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: Claude Code PR Review
2+
3+
on:
4+
issue_comment:
5+
types: [ created ]
6+
pull_request_review_comment:
7+
types: [ created ]
8+
9+
jobs:
10+
claude-review:
11+
uses: atko-cic/ai-pr-analyzer-gh-action/.github/workflows/claude-code-review.yml@main

.github/workflows/sca_scan.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
name: SCA
3+
4+
on:
5+
push:
6+
branches: ["master", "main"]
7+
8+
jobs:
9+
snyk-cli:
10+
uses: atko-security/devsecops-tooling/.github/workflows/sca-scan.yml@main
11+
secrets: inherit

0 commit comments

Comments
 (0)