From 1ca1e05830b6c3d2f2aa7152ee0880e785804a49 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Thu, 19 Feb 2026 00:49:31 +0530 Subject: [PATCH 1/3] Feat: Modified method signatures --- README.md | 40 +----- .../com/auth0/AbstractAuthentication.java | 6 +- .../com/auth0/AllowedDPoPAuthentication.java | 2 +- .../src/main/java/com/auth0/AuthClient.java | 4 +- .../com/auth0/DisabledDPoPAuthentication.java | 2 +- .../com/auth0/examples/Auth0ApiExample.java | 1 - .../com/auth0/validators/JWTValidator.java | 24 ++-- .../com/auth0/AbstractAuthenticationTest.java | 6 +- .../auth0/AllowedDPoPAuthenticationTest.java | 6 +- .../auth0/DisabledDPoPAuthenticationTest.java | 4 +- .../auth0/RequiredDPoPAuthenticationTest.java | 2 +- .../auth0/validators/JWTValidatorTest.java | 26 ++-- auth0-springboot-api/EXAMPLES.md | 128 ------------------ auth0-springboot-api/README.md | 90 ++++++++---- auth0-springboot-api/build.gradle | 3 +- .../spring/boot/Auth0AuthenticationToken.java | 42 +++++- .../boot/Auth0AuthenticationTokenTest.java | 13 -- 17 files changed, 144 insertions(+), 255 deletions(-) diff --git a/README.md b/README.md index 885a754..3649f1e 100644 --- a/README.md +++ b/README.md @@ -51,45 +51,7 @@ The core library (`auth0-api-java`) is currently an internal module used by the - JWT validation with Auth0 JWKS integration - DPoP proof validation per [RFC 9449](https://datatracker.ietf.org/doc/html/rfc9449) - Flexible authentication strategies -- Comprehensive claim validation -## 🔧 Advanced Configuration - -### Custom Claim Validation - -While the Spring Boot integration provides automatic validation, developers can access the underlying `auth0-api-java` validation utilities for custom scenarios: - -```java -@RestController -public class AdvancedController { - - @Autowired - private AuthClient authClient; - - @GetMapping("/api/custom-validation") - public ResponseEntity customValidation(HttpServletRequest request) { - try { - String token = extractTokenFromRequest(request); - JWTValidator validator = new JWTValidator(authClient.getAuthOptions()); - - DecodedJWT jwt = validator.validateTokenWithClaimEquals(token, "role", "admin"); - - return ResponseEntity.ok("Advanced validation passed"); - - } catch (BaseAuthException e) { - return ResponseEntity.status(401).body("Validation failed: " + e.getMessage()); - } - } - - private String extractTokenFromRequest(HttpServletRequest request) { - String authHeader = request.getHeader("Authorization"); - if (authHeader != null && authHeader.startsWith("Bearer ")) { - return authHeader.substring(7); - } - throw new IllegalArgumentException("No Bearer token found"); - } -} -``` ## 📚 Documentation @@ -135,7 +97,7 @@ The core library (`auth0-api-java`) is bundled as an internal dependency within 4. Add tests for new functionality 5. Ensure all tests pass: `./gradlew test` 6. Ensure your commits are signed -7. 7Submit a pull request +7. Submit a pull request ## 📄 License diff --git a/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java b/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java index a915d7c..6a3634a 100644 --- a/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java +++ b/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java @@ -28,9 +28,9 @@ protected AbstractAuthentication(JWTValidator jwtValidator, TokenExtractor extra /** * Concrete method to validate Bearer token headers and JWT claims. */ - protected DecodedJWT validateBearerToken(Map headers) throws BaseAuthException { + protected DecodedJWT validateBearerToken(Map headers, HttpRequestInfo httpRequestInfo) throws BaseAuthException { AuthToken authToken = extractor.extractBearer(headers); - return jwtValidator.validateToken(authToken.getAccessToken()); + return jwtValidator.validateToken(authToken.getAccessToken(), httpRequestInfo); } /** @@ -42,7 +42,7 @@ protected DecodedJWT validateDpopTokenAndProof(Map headers, Http AuthValidatorHelper.validateHttpMethodAndHttpUrl(requestInfo); AuthToken authToken = extractor.extractDPoPProofAndDPoPToken(headers); - DecodedJWT decodedJwtToken = jwtValidator.validateToken(authToken.getAccessToken()); + DecodedJWT decodedJwtToken = jwtValidator.validateToken(authToken.getAccessToken(), requestInfo); dpopProofValidator.validate(authToken.getProof(), decodedJwtToken, requestInfo); diff --git a/auth0-api-java/src/main/java/com/auth0/AllowedDPoPAuthentication.java b/auth0-api-java/src/main/java/com/auth0/AllowedDPoPAuthentication.java index eb864b2..5b14fae 100644 --- a/auth0-api-java/src/main/java/com/auth0/AllowedDPoPAuthentication.java +++ b/auth0-api-java/src/main/java/com/auth0/AllowedDPoPAuthentication.java @@ -37,7 +37,7 @@ public AuthenticationContext authenticate(Map headers, HttpReque scheme = extractor.getScheme(normalizedHeader); if (scheme.equalsIgnoreCase(AuthConstants.BEARER_SCHEME)) { - DecodedJWT jwtToken = validateBearerToken(normalizedHeader); + DecodedJWT jwtToken = validateBearerToken(normalizedHeader, requestInfo); AuthValidatorHelper.validateNoDpopPresence(normalizedHeader, jwtToken); return buildContext(jwtToken); } diff --git a/auth0-api-java/src/main/java/com/auth0/AuthClient.java b/auth0-api-java/src/main/java/com/auth0/AuthClient.java index 4be52b7..cd2c99b 100644 --- a/auth0-api-java/src/main/java/com/auth0/AuthClient.java +++ b/auth0-api-java/src/main/java/com/auth0/AuthClient.java @@ -2,10 +2,10 @@ import com.auth0.exception.BaseAuthException; import com.auth0.models.AuthenticationContext; -import com.auth0.validators.DPoPProofValidator; -import com.auth0.validators.JWTValidator; import com.auth0.models.AuthOptions; import com.auth0.models.HttpRequestInfo; +import com.auth0.validators.DPoPProofValidator; +import com.auth0.validators.JWTValidator; import java.util.Map; diff --git a/auth0-api-java/src/main/java/com/auth0/DisabledDPoPAuthentication.java b/auth0-api-java/src/main/java/com/auth0/DisabledDPoPAuthentication.java index 8c5a6a6..6f166f8 100644 --- a/auth0-api-java/src/main/java/com/auth0/DisabledDPoPAuthentication.java +++ b/auth0-api-java/src/main/java/com/auth0/DisabledDPoPAuthentication.java @@ -28,7 +28,7 @@ public AuthenticationContext authenticate(Map headers, HttpReque Map normalizedHeader = normalize(headers); try { - DecodedJWT jwt = validateBearerToken(normalizedHeader); + DecodedJWT jwt = validateBearerToken(normalizedHeader, requestInfo); return buildContext(jwt); } catch (BaseAuthException ex){ diff --git a/auth0-api-java/src/main/java/com/auth0/examples/Auth0ApiExample.java b/auth0-api-java/src/main/java/com/auth0/examples/Auth0ApiExample.java index 918574d..cde1962 100644 --- a/auth0-api-java/src/main/java/com/auth0/examples/Auth0ApiExample.java +++ b/auth0-api-java/src/main/java/com/auth0/examples/Auth0ApiExample.java @@ -6,7 +6,6 @@ import com.auth0.models.AuthOptions; import com.auth0.models.AuthenticationContext; import com.auth0.models.HttpRequestInfo; -import com.auth0.validators.JWTValidator; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; diff --git a/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java b/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java index af17a9a..06a9ebb 100644 --- a/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java +++ b/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java @@ -11,6 +11,8 @@ import com.auth0.jwk.UrlJwkProvider; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; +import com.auth0.models.HttpRequestInfo; + import java.security.interfaces.RSAPublicKey; import static com.auth0.jwt.JWT.require; @@ -64,7 +66,7 @@ public JWTValidator(AuthOptions authOptions, JwkProvider jwkProvider) { * @return the decoded and verified JWT * @throws BaseAuthException if validation fails */ - public DecodedJWT validateToken(String token) throws BaseAuthException { + public DecodedJWT validateToken(String token, HttpRequestInfo httpRequestInfo) throws BaseAuthException { if (token == null || token.trim().isEmpty()) { throw new MissingRequiredArgumentException("access_token"); @@ -89,9 +91,9 @@ public DecodedJWT validateToken(String token) throws BaseAuthException { /** * Validates a JWT and ensures all required scopes are present. */ - public DecodedJWT validateTokenWithRequiredScopes(String token, String... requiredScopes) + public DecodedJWT validateTokenWithRequiredScopes(String token, HttpRequestInfo httpRequestInfo, String... requiredScopes) throws BaseAuthException { - DecodedJWT jwt = validateToken(token); + DecodedJWT jwt = validateToken(token, httpRequestInfo); try { ClaimValidator.checkRequiredScopes(jwt, requiredScopes); return jwt; @@ -103,9 +105,9 @@ public DecodedJWT validateTokenWithRequiredScopes(String token, String... requir /** * Validates a JWT and ensures it has *any* of the provided scopes. */ - public DecodedJWT validateTokenWithAnyScope(String token, String... scopes) + public DecodedJWT validateTokenWithAnyScope(String token, HttpRequestInfo httpRequestInfo, String... scopes) throws BaseAuthException { - DecodedJWT jwt = validateToken(token); + DecodedJWT jwt = validateToken(token, httpRequestInfo); try { ClaimValidator.checkAnyScope(jwt, scopes); return jwt; @@ -117,9 +119,9 @@ public DecodedJWT validateTokenWithAnyScope(String token, String... scopes) /** * Validates a JWT and ensures a claim equals the expected value. */ - public DecodedJWT validateTokenWithClaimEquals(String token, String claim, Object expected) + public DecodedJWT validateTokenWithClaimEquals(String token, HttpRequestInfo httpRequestInfo, String claim, Object expected) throws BaseAuthException { - DecodedJWT jwt = validateToken(token); + DecodedJWT jwt = validateToken(token, httpRequestInfo); try { ClaimValidator.checkClaimEquals(jwt, claim, expected); return jwt; @@ -131,9 +133,9 @@ public DecodedJWT validateTokenWithClaimEquals(String token, String claim, Objec /** * Validates a JWT and ensures a claim includes all expected values. */ - public DecodedJWT validateTokenWithClaimIncludes(String token, String claim, Object... expectedValues) + public DecodedJWT validateTokenWithClaimIncludes(String token, HttpRequestInfo httpRequestInfo, String claim, Object... expectedValues) throws BaseAuthException { - DecodedJWT jwt = validateToken(token); + DecodedJWT jwt = validateToken(token, httpRequestInfo); try { ClaimValidator.checkClaimIncludes(jwt, claim, expectedValues); return jwt; @@ -142,9 +144,9 @@ public DecodedJWT validateTokenWithClaimIncludes(String token, String claim, Obj } } - public DecodedJWT validateTokenWithClaimIncludesAny(String token, String claim, Object... expectedValues) + public DecodedJWT validateTokenWithClaimIncludesAny(String token, HttpRequestInfo httpRequestInfo, String claim, Object... expectedValues) throws BaseAuthException { - DecodedJWT jwt = validateToken(token); + DecodedJWT jwt = validateToken(token, httpRequestInfo); try { ClaimValidator.checkClaimIncludesAny(jwt, claim, expectedValues); return jwt; diff --git a/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java index c26326a..3067578 100644 --- a/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java @@ -80,12 +80,12 @@ public void validateBearerToken_shouldExtractAndValidate() throws Exception { DecodedJWT jwt = mock(DecodedJWT.class); when(extractor.extractBearer(anyMap())).thenReturn(token); - when(jwtValidator.validateToken("access")).thenReturn(jwt); + when(jwtValidator.validateToken("access", null)).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "Bearer access"); - DecodedJWT result = authSystem.validateBearerToken(headers); + DecodedJWT result = authSystem.validateBearerToken(headers, null); assertThat(result).isSameAs(jwt); } @@ -98,7 +98,7 @@ public void validateDpopTokenAndProof_shouldValidateEverything() throws Exceptio new HttpRequestInfo("GET", "https://api.example.com", null); when(extractor.extractDPoPProofAndDPoPToken(anyMap())).thenReturn(token); - when(jwtValidator.validateToken("access")).thenReturn(jwt); + when(jwtValidator.validateToken(eq("access"), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "DPoP access"); diff --git a/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java index 436ce55..f9bc2c3 100644 --- a/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java @@ -47,7 +47,7 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { when(extractor.extractBearer(anyMap())).thenReturn( new AuthToken("token", null, null) ); - when(jwtValidator.validateToken("token")).thenReturn(jwt); + when(jwtValidator.validateToken("token", null)).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "Bearer token"); @@ -55,7 +55,7 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { AuthenticationContext ctx = auth.authenticate(headers, null); assertThat(ctx).isNotNull(); - verify(jwtValidator).validateToken("token"); + verify(jwtValidator).validateToken("token", null); verifyNoInteractions(dpopProofValidator); } @@ -69,7 +69,7 @@ public void authenticate_shouldAcceptDpopToken() throws Exception { when(extractor.extractDPoPProofAndDPoPToken(anyMap())).thenReturn( new com.auth0.models.AuthToken("token", "proof", null) ); - when(jwtValidator.validateToken("token")).thenReturn(jwt); + when(jwtValidator.validateToken(eq("token"), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "DPoP token"); headers.put("dpop", "proof"); diff --git a/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java index 5fa11dd..f92556f 100644 --- a/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java @@ -33,7 +33,7 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { when(extractor.extractBearer(anyMap())).thenReturn( new com.auth0.models.AuthToken("token", null, null) ); - when(jwtValidator.validateToken("token")).thenReturn(jwt); + when(jwtValidator.validateToken("token", null)).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "Bearer token"); @@ -43,7 +43,7 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { assertThat(ctx).isNotNull(); - verify(jwtValidator).validateToken("token"); + verify(jwtValidator).validateToken("token", null); } @Test diff --git a/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java index a1cc9ef..2e5dd7e 100644 --- a/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java @@ -39,7 +39,7 @@ public void authenticate_shouldAcceptDpopToken() throws Exception { when(extractor.extractDPoPProofAndDPoPToken(anyMap())).thenReturn( new com.auth0.models.AuthToken("token", "proof", null) ); - when(jwtValidator.validateToken("token")).thenReturn(jwt); + when(jwtValidator.validateToken(eq("token"), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "DPoP token"); diff --git a/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java b/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java index 21abbde..2ec5d48 100644 --- a/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java +++ b/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java @@ -80,7 +80,7 @@ public void constructor_shouldRejectNullJwkProvider() { public void validateToken_success() throws Exception { String token = validToken(); - DecodedJWT jwt = validator.validateToken(token); + DecodedJWT jwt = validator.validateToken(token, null); assertThat(jwt.getIssuer()).isEqualTo(ISSUER); assertThat(jwt.getAudience()).contains(AUDIENCE); @@ -89,7 +89,7 @@ public void validateToken_success() throws Exception { @Test(expected = MissingRequiredArgumentException.class) public void validateToken_shouldRejectNullToken() throws Exception { - validator.validateToken(null); + validator.validateToken(null, null); } @Test(expected = VerifyAccessTokenException.class) @@ -100,14 +100,14 @@ public void validateToken_shouldRejectInvalidSignature() throws Exception { when(jwk.getPublicKey()).thenReturn(wrongKey); - validator.validateToken(validToken()); + validator.validateToken(validToken(), null); } @Test public void validateTokenWithRequiredScopes_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithRequiredScopes(token, "read"); + DecodedJWT jwt = validator.validateTokenWithRequiredScopes(token, null, "read"); assertThat(jwt).isNotNull(); } @@ -116,14 +116,14 @@ public void validateTokenWithRequiredScopes_success() throws Exception { public void validateTokenWithRequiredScopes_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithRequiredScopes(token, "admin"); + validator.validateTokenWithRequiredScopes(token, null, "admin"); } @Test public void validateTokenWithAnyScope_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithAnyScope(token, "admin", "write"); + DecodedJWT jwt = validator.validateTokenWithAnyScope(token, null, "admin", "write"); assertThat(jwt).isNotNull(); } @@ -132,14 +132,14 @@ public void validateTokenWithAnyScope_success() throws Exception { public void validateTokenWithAnyScope_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithAnyScope(token, "admin"); + validator.validateTokenWithAnyScope(token, null, "admin"); } @Test public void validateTokenWithClaimEquals_success() throws Exception { String token = tokenWithEmail("a@b.com"); - DecodedJWT jwt = validator.validateTokenWithClaimEquals(token, "email", "a@b.com"); + DecodedJWT jwt = validator.validateTokenWithClaimEquals(token, null, "email", "a@b.com"); assertThat(jwt).isNotNull(); } @@ -148,14 +148,14 @@ public void validateTokenWithClaimEquals_success() throws Exception { public void validateTokenWithClaimEquals_failure() throws Exception { String token = tokenWithEmail("a@b.com"); - validator.validateTokenWithClaimEquals(token, "email", "x@y.com"); + validator.validateTokenWithClaimEquals(token, null, "email", "x@y.com"); } @Test public void validateTokenWithClaimIncludes_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithClaimIncludes(token, "scope", "read"); + DecodedJWT jwt = validator.validateTokenWithClaimIncludes(token, null, "scope", "read"); assertThat(jwt).isNotNull(); } @@ -164,14 +164,14 @@ public void validateTokenWithClaimIncludes_success() throws Exception { public void validateTokenWithClaimIncludes_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithClaimIncludes(token, "scope", "admin"); + validator.validateTokenWithClaimIncludes(token, null, "scope", "admin"); } @Test public void validateTokenWithClaimIncludesAny_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithClaimIncludesAny(token, "scope", "admin", "write"); + DecodedJWT jwt = validator.validateTokenWithClaimIncludesAny(token, null, "scope", "admin", "write"); assertThat(jwt).isNotNull(); } @@ -180,7 +180,7 @@ public void validateTokenWithClaimIncludesAny_success() throws Exception { public void validateTokenWithClaimIncludesAny_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithClaimIncludesAny(token, "scope", "admin"); + validator.validateTokenWithClaimIncludesAny(token, null, "scope", "admin"); } @Test diff --git a/auth0-springboot-api/EXAMPLES.md b/auth0-springboot-api/EXAMPLES.md index 18993af..dacec30 100644 --- a/auth0-springboot-api/EXAMPLES.md +++ b/auth0-springboot-api/EXAMPLES.md @@ -104,30 +104,6 @@ public class UserController { } ``` -### Custom Error Handling - -```java -@ControllerAdvice -public class AuthErrorHandler { - - @ExceptionHandler(BaseAuthException.class) - public ResponseEntity> handleAuthException(BaseAuthException ex) { - Map error = Map.of( - "error", ex.getError(), - "error_description", ex.getMessage(), - "status", ex.getStatusCode() - ); - - HttpHeaders headers = new HttpHeaders(); - if (ex.getWwwAuthenticateHeader() != null) { - headers.add("WWW-Authenticate", ex.getWwwAuthenticateHeader()); - } - - return new ResponseEntity<>(error, headers, HttpStatus.valueOf(ex.getStatusCode())); - } -} -``` - ## DPoP Authentication [DPoP](https://www.rfc-editor.org/rfc/rfc9449.html) (Demonstrating Proof of Possession) is an application-level mechanism for sender-constraining OAuth 2.0 access and refresh tokens. @@ -291,110 +267,6 @@ public class CustomScopeController { } ``` -## Testing - -### Unit Test Example - -```java -@WebMvcTest(ApiController.class) -class ApiControllerTest { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private Auth0AuthenticationFilter authFilter; - - @Test - void testProtectedEndpointWithValidToken() throws Exception { - // Mock authentication - Auth0AuthenticationToken mockAuth = mock(Auth0AuthenticationToken.class); - when(mockAuth.getName()).thenReturn("user123"); - when(mockAuth.isAuthenticated()).thenReturn(true); - - mockMvc.perform(get("/api/protected") - .with(authentication(mockAuth))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.user").value("user123")) - .andExpect(jsonPath("$.authenticated").value(true)); - } - - @Test - void testPublicEndpoint() throws Exception { - mockMvc.perform(get("/api/public")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.message").value("Public endpoint - no token required")); - } -} -``` - -### Integration Test Example - -```java -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@TestPropertySource(properties = { - "auth0.domain=test-tenant.auth0.com", - "auth0.audience=https://test-api.example.com", - "auth0.dpopMode=ALLOWED" -}) -class AuthIntegrationTest { - - @Autowired - private TestRestTemplate restTemplate; - - @Test - void testProtectedEndpointWithBearerToken() { - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Bearer " + getValidJwtToken()); - - HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = restTemplate.exchange( - "/api/protected", - HttpMethod.GET, - entity, - Map.class - ); - - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).containsKey("user"); - } - - @Test - void testProtectedEndpointWithDPoPToken() { - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "DPoP " + getValidDPoPToken()); - headers.add("DPoP", getValidDPoPProof()); - - HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = restTemplate.exchange( - "/api/protected", - HttpMethod.GET, - entity, - Map.class - ); - - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).containsKey("user"); - } - - private String getValidJwtToken() { - // Generate or mock a valid JWT token for testing - // Implementation depends on your testing strategy - return "eyJ0eXAiOiJKV1Q..."; - } - - private String getValidDPoPToken() { - // Generate or mock a valid DPoP-bound access token - return "eyJ0eXAiOiJKV1Q..."; - } - - private String getValidDPoPProof() { - // Generate or mock a valid DPoP proof - return "eyJ0eXAiOiJkcG9wK2p3dCI..."; - } -} -``` - ## Configuration Reference ### Complete Configuration Example diff --git a/auth0-springboot-api/README.md b/auth0-springboot-api/README.md index fd97322..a7f470c 100644 --- a/auth0-springboot-api/README.md +++ b/auth0-springboot-api/README.md @@ -219,28 +219,40 @@ public class CustomController { } ``` -### Custom Authentication Handlers +### Custom Claim Validation -Access JWT claims and customize authentication logic: +Access JWT claims directly through `Auth0AuthenticationToken`'s clean API: ```java -@GetMapping("/api/user-profile") -public ResponseEntity> userProfile(Authentication authentication) { - // Cast to Auth0 authentication token to access claims - Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication; - Map claims = auth0Token.getAuthenticationContext().getClaims(); +@RestController +public class UserController { + + @GetMapping("/api/user-profile") + public ResponseEntity> userProfile(Authentication authentication) { + // Cast to Auth0AuthenticationToken to access Auth0-specific features + Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication; - String userId = (String) claims.get("sub"); - String email = (String) claims.get("email"); + Map profile = new HashMap<>(); + profile.put("userId", auth0Token.getClaim("sub")); + profile.put("email", auth0Token.getClaim("email")); + profile.put("scopes", auth0Token.getScopes()); // Set of scopes + profile.put("authorities", authentication.getAuthorities()); // Spring Security authorities - String scopes = (String) claims.get("scope"); + return ResponseEntity.ok(profile); + } - Map profile = new HashMap<>(); - profile.put("userId", userId); - profile.put("email", email); - profile.put("scopes", scopes); + @GetMapping("/api/admin") + public ResponseEntity adminEndpoint(Authentication authentication) { + // Validate custom claims using individual claim access + Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication; - return ResponseEntity.ok(profile); + String userRole = (String) auth0Token.getClaim("role"); + if ("admin".equals(userRole)) { + return ResponseEntity.ok("Admin access granted"); + } else { + return ResponseEntity.status(403).body("Admin role required"); + } + } } ``` @@ -256,7 +268,7 @@ public class SecurityConfig { return http.csrf(csrf -> csrf.disable()) .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth - .requestMatchers("/api/admin/**").hasAuthority("admin") + .requestMatchers("/api/admin/**").authenticated() .requestMatchers("/api/users/**").hasAnyAuthority("SCOPE_read:messages") .requestMatchers("/api/protected").authenticated() .anyRequest().permitAll()) @@ -264,20 +276,43 @@ public class SecurityConfig { .build(); } } +``` -@Autowired -private ScopeValidator scopeValidator; -@GetMapping("/admin") -public ResponseEntity> adminEndpoint(Authentication authentication) { - System.out.println("🔐 Received request for /api/admin resource by user: " + authentication.getName()); - if (!scopeValidator.hasRequiredScopes(authentication, "read:messages")) { - return ResponseEntity.status(HttpStatus.FORBIDDEN) - .body(Map.of("error", "insufficient_scope")); - } - return ResponseEntity.ok(Map.of("message", "Admin access granted")); + +For custom scope validation in controllers: + +```java +@Component +public class ScopeValidator { + public boolean hasRequiredScopes(Authentication authentication, String... requiredScopes) { + if (!(authentication instanceof Auth0AuthenticationToken)) { + return false; + } + Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication; + + Set tokenScopes = auth0Token.getScopes(); + return tokenScopes.containsAll(Arrays.asList(requiredScopes)); + } +} + +@RestController +public class AdminController { + + @Autowired + private ScopeValidator scopeValidator; + + @GetMapping("/api/admin") + public ResponseEntity> adminEndpoint(Authentication authentication) { + if (!scopeValidator.hasRequiredScopes(authentication, "admin")) { + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body(Map.of("error", "insufficient_scope")); + } + return ResponseEntity.ok(Map.of("message", "Admin access granted")); + } } ``` + ## Examples For comprehensive examples and use cases, see the playground application: @@ -306,9 +341,8 @@ public class ApiController { @GetMapping("/conditional") public ResponseEntity conditionalEndpoint(Authentication authentication) { Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication; - Map claims = auth0Token.getAuthenticationContext().getClaims(); - String userRole = (String) claims.get("role"); + String userRole = (String) auth0Token.getClaim("role"); if ("admin".equals(userRole)) { return ResponseEntity.ok("Admin access granted"); } else { diff --git a/auth0-springboot-api/build.gradle b/auth0-springboot-api/build.gradle index 07da28a..4cd4e07 100644 --- a/auth0-springboot-api/build.gradle +++ b/auth0-springboot-api/build.gradle @@ -22,8 +22,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' - // Internal dependency - not exposed to consumers - api project(':auth0-api-java') + implementation project(':auth0-api-java') implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'org.apache.httpcomponents:httpclient:4.5.14' diff --git a/auth0-springboot-api/src/main/java/com/auth0/spring/boot/Auth0AuthenticationToken.java b/auth0-springboot-api/src/main/java/com/auth0/spring/boot/Auth0AuthenticationToken.java index fab97c8..ed41b0b 100644 --- a/auth0-springboot-api/src/main/java/com/auth0/spring/boot/Auth0AuthenticationToken.java +++ b/auth0-springboot-api/src/main/java/com/auth0/spring/boot/Auth0AuthenticationToken.java @@ -8,6 +8,8 @@ import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; /** @@ -76,11 +78,43 @@ public Object getPrincipal() { } /** - * Returns the underlying {@link AuthenticationContext} containing validated JWT claims. + * Returns the JWT claims from the authenticated token. + *

+ * Provides access to all JWT claims without exposing internal authentication + * context. + * + * @return a map containing all JWT claims + */ + public Map getClaims() { + return authenticationContext.getClaims(); + } + + /** + * Returns the scopes from the JWT as a set of strings. + *

+ * Extracts and parses the "scope" claim into individual scope strings. + * + * @return a set of scope strings, or empty set if no scopes present + */ + public Set getScopes() { + Object scopeClaim = authenticationContext.getClaims().get("scope"); + if (scopeClaim instanceof String && !((String) scopeClaim).isBlank()) { + String scopes = (String) scopeClaim; + return Set.of(scopes.trim().split("\\s+")); + } + return Set.of(); + } + + /** + * Returns a specific claim value from the JWT. + *

+ * Convenience method for accessing individual claims without getting the full + * claims map. * - * @return the authentication context + * @param claimName the name of the claim to retrieve + * @return the claim value, or null if not present */ - public AuthenticationContext getAuthenticationContext() { - return authenticationContext; + public Object getClaim(String claimName) { + return authenticationContext.getClaims().get(claimName); } } diff --git a/auth0-springboot-api/src/test/java/com/auth0/spring/boot/Auth0AuthenticationTokenTest.java b/auth0-springboot-api/src/test/java/com/auth0/spring/boot/Auth0AuthenticationTokenTest.java index f122b91..06bcb22 100644 --- a/auth0-springboot-api/src/test/java/com/auth0/spring/boot/Auth0AuthenticationTokenTest.java +++ b/auth0-springboot-api/src/test/java/com/auth0/spring/boot/Auth0AuthenticationTokenTest.java @@ -159,19 +159,6 @@ void getCredentials_shouldReturnNull() { assertNull(token.getCredentials()); } - @Test - @DisplayName("Should return authentication context from getter") - void getAuthenticationContext_shouldReturnContext() { - AuthenticationContext context = mock(AuthenticationContext.class); - Map claims = new HashMap<>(); - claims.put("sub", "auth0|123456789"); - when(context.getClaims()).thenReturn(claims); - - Auth0AuthenticationToken token = new Auth0AuthenticationToken(context); - - assertEquals(context, token.getAuthenticationContext()); - } - @Test @DisplayName("Should create authorities with scopes containing special characters") void createAuthorities_shouldHandleSpecialCharacters_inScopes() { From 33c81474e3e9dfe88f7a062dc6f7e0d5710c6ad7 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Thu, 19 Feb 2026 10:34:21 +0530 Subject: [PATCH 2/3] Added headers in validateToken method --- .../com/auth0/AbstractAuthentication.java | 4 +-- .../com/auth0/validators/JWTValidator.java | 23 ++++++++-------- .../com/auth0/AbstractAuthenticationTest.java | 4 +-- .../auth0/AllowedDPoPAuthenticationTest.java | 10 ++++--- .../auth0/DisabledDPoPAuthenticationTest.java | 8 ++++-- .../auth0/RequiredDPoPAuthenticationTest.java | 2 +- .../auth0/validators/JWTValidatorTest.java | 27 ++++++++++--------- 7 files changed, 44 insertions(+), 34 deletions(-) diff --git a/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java b/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java index 6a3634a..a091a32 100644 --- a/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java +++ b/auth0-api-java/src/main/java/com/auth0/AbstractAuthentication.java @@ -30,7 +30,7 @@ protected AbstractAuthentication(JWTValidator jwtValidator, TokenExtractor extra */ protected DecodedJWT validateBearerToken(Map headers, HttpRequestInfo httpRequestInfo) throws BaseAuthException { AuthToken authToken = extractor.extractBearer(headers); - return jwtValidator.validateToken(authToken.getAccessToken(), httpRequestInfo); + return jwtValidator.validateToken(authToken.getAccessToken(), headers, httpRequestInfo); } /** @@ -42,7 +42,7 @@ protected DecodedJWT validateDpopTokenAndProof(Map headers, Http AuthValidatorHelper.validateHttpMethodAndHttpUrl(requestInfo); AuthToken authToken = extractor.extractDPoPProofAndDPoPToken(headers); - DecodedJWT decodedJwtToken = jwtValidator.validateToken(authToken.getAccessToken(), requestInfo); + DecodedJWT decodedJwtToken = jwtValidator.validateToken(authToken.getAccessToken(), headers, requestInfo); dpopProofValidator.validate(authToken.getProof(), decodedJwtToken, requestInfo); diff --git a/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java b/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java index 06a9ebb..9d655dc 100644 --- a/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java +++ b/auth0-api-java/src/main/java/com/auth0/validators/JWTValidator.java @@ -14,6 +14,7 @@ import com.auth0.models.HttpRequestInfo; import java.security.interfaces.RSAPublicKey; +import java.util.Map; import static com.auth0.jwt.JWT.require; @@ -66,7 +67,7 @@ public JWTValidator(AuthOptions authOptions, JwkProvider jwkProvider) { * @return the decoded and verified JWT * @throws BaseAuthException if validation fails */ - public DecodedJWT validateToken(String token, HttpRequestInfo httpRequestInfo) throws BaseAuthException { + public DecodedJWT validateToken(String token, Map headers, HttpRequestInfo httpRequestInfo) throws BaseAuthException { if (token == null || token.trim().isEmpty()) { throw new MissingRequiredArgumentException("access_token"); @@ -91,9 +92,9 @@ public DecodedJWT validateToken(String token, HttpRequestInfo httpRequestInfo) t /** * Validates a JWT and ensures all required scopes are present. */ - public DecodedJWT validateTokenWithRequiredScopes(String token, HttpRequestInfo httpRequestInfo, String... requiredScopes) + public DecodedJWT validateTokenWithRequiredScopes(String token, Map headers, HttpRequestInfo httpRequestInfo, String... requiredScopes) throws BaseAuthException { - DecodedJWT jwt = validateToken(token, httpRequestInfo); + DecodedJWT jwt = validateToken(token, headers, httpRequestInfo); try { ClaimValidator.checkRequiredScopes(jwt, requiredScopes); return jwt; @@ -105,9 +106,9 @@ public DecodedJWT validateTokenWithRequiredScopes(String token, HttpRequestInfo /** * Validates a JWT and ensures it has *any* of the provided scopes. */ - public DecodedJWT validateTokenWithAnyScope(String token, HttpRequestInfo httpRequestInfo, String... scopes) + public DecodedJWT validateTokenWithAnyScope(String token, Map headers, HttpRequestInfo httpRequestInfo, String... scopes) throws BaseAuthException { - DecodedJWT jwt = validateToken(token, httpRequestInfo); + DecodedJWT jwt = validateToken(token, headers, httpRequestInfo); try { ClaimValidator.checkAnyScope(jwt, scopes); return jwt; @@ -119,9 +120,9 @@ public DecodedJWT validateTokenWithAnyScope(String token, HttpRequestInfo httpRe /** * Validates a JWT and ensures a claim equals the expected value. */ - public DecodedJWT validateTokenWithClaimEquals(String token, HttpRequestInfo httpRequestInfo, String claim, Object expected) + public DecodedJWT validateTokenWithClaimEquals(String token, Map headers, HttpRequestInfo httpRequestInfo, String claim, Object expected) throws BaseAuthException { - DecodedJWT jwt = validateToken(token, httpRequestInfo); + DecodedJWT jwt = validateToken(token, headers, httpRequestInfo); try { ClaimValidator.checkClaimEquals(jwt, claim, expected); return jwt; @@ -133,9 +134,9 @@ public DecodedJWT validateTokenWithClaimEquals(String token, HttpRequestInfo htt /** * Validates a JWT and ensures a claim includes all expected values. */ - public DecodedJWT validateTokenWithClaimIncludes(String token, HttpRequestInfo httpRequestInfo, String claim, Object... expectedValues) + public DecodedJWT validateTokenWithClaimIncludes(String token, Map headers, HttpRequestInfo httpRequestInfo, String claim, Object... expectedValues) throws BaseAuthException { - DecodedJWT jwt = validateToken(token, httpRequestInfo); + DecodedJWT jwt = validateToken(token, headers, httpRequestInfo); try { ClaimValidator.checkClaimIncludes(jwt, claim, expectedValues); return jwt; @@ -144,9 +145,9 @@ public DecodedJWT validateTokenWithClaimIncludes(String token, HttpRequestInfo h } } - public DecodedJWT validateTokenWithClaimIncludesAny(String token, HttpRequestInfo httpRequestInfo, String claim, Object... expectedValues) + public DecodedJWT validateTokenWithClaimIncludesAny(String token, Map headers, HttpRequestInfo httpRequestInfo, String claim, Object... expectedValues) throws BaseAuthException { - DecodedJWT jwt = validateToken(token, httpRequestInfo); + DecodedJWT jwt = validateToken(token, headers, httpRequestInfo); try { ClaimValidator.checkClaimIncludesAny(jwt, claim, expectedValues); return jwt; diff --git a/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java index 3067578..0881b37 100644 --- a/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/AbstractAuthenticationTest.java @@ -80,7 +80,7 @@ public void validateBearerToken_shouldExtractAndValidate() throws Exception { DecodedJWT jwt = mock(DecodedJWT.class); when(extractor.extractBearer(anyMap())).thenReturn(token); - when(jwtValidator.validateToken("access", null)).thenReturn(jwt); + when(jwtValidator.validateToken(eq("access"), anyMap(), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "Bearer access"); @@ -98,7 +98,7 @@ public void validateDpopTokenAndProof_shouldValidateEverything() throws Exceptio new HttpRequestInfo("GET", "https://api.example.com", null); when(extractor.extractDPoPProofAndDPoPToken(anyMap())).thenReturn(token); - when(jwtValidator.validateToken(eq("access"), any())).thenReturn(jwt); + when(jwtValidator.validateToken(eq("access"), anyMap(), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "DPoP access"); diff --git a/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java index f9bc2c3..d350589 100644 --- a/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/AllowedDPoPAuthenticationTest.java @@ -47,7 +47,11 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { when(extractor.extractBearer(anyMap())).thenReturn( new AuthToken("token", null, null) ); - when(jwtValidator.validateToken("token", null)).thenReturn(jwt); + + Map normalizedHeaders = new HashMap<>(); + normalizedHeaders.put("authorization", "Bearer token"); + + when(jwtValidator.validateToken(eq("token"), eq(normalizedHeaders), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "Bearer token"); @@ -55,7 +59,7 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { AuthenticationContext ctx = auth.authenticate(headers, null); assertThat(ctx).isNotNull(); - verify(jwtValidator).validateToken("token", null); + verify(jwtValidator).validateToken("token", normalizedHeaders, null); verifyNoInteractions(dpopProofValidator); } @@ -69,7 +73,7 @@ public void authenticate_shouldAcceptDpopToken() throws Exception { when(extractor.extractDPoPProofAndDPoPToken(anyMap())).thenReturn( new com.auth0.models.AuthToken("token", "proof", null) ); - when(jwtValidator.validateToken(eq("token"), any())).thenReturn(jwt); + when(jwtValidator.validateToken(eq("token"), anyMap(), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "DPoP token"); headers.put("dpop", "proof"); diff --git a/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java index f92556f..38d3dec 100644 --- a/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/DisabledDPoPAuthenticationTest.java @@ -33,7 +33,11 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { when(extractor.extractBearer(anyMap())).thenReturn( new com.auth0.models.AuthToken("token", null, null) ); - when(jwtValidator.validateToken("token", null)).thenReturn(jwt); + + Map normalizedHeaders = new HashMap<>(); + normalizedHeaders.put("authorization", "Bearer token"); + + when(jwtValidator.validateToken(eq("token"), eq(normalizedHeaders), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "Bearer token"); @@ -43,7 +47,7 @@ public void authenticate_shouldAcceptBearerToken() throws Exception { assertThat(ctx).isNotNull(); - verify(jwtValidator).validateToken("token", null); + verify(jwtValidator).validateToken("token", normalizedHeaders, null); } @Test diff --git a/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java b/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java index 2e5dd7e..dfd4e02 100644 --- a/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java +++ b/auth0-api-java/src/test/java/com/auth0/RequiredDPoPAuthenticationTest.java @@ -39,7 +39,7 @@ public void authenticate_shouldAcceptDpopToken() throws Exception { when(extractor.extractDPoPProofAndDPoPToken(anyMap())).thenReturn( new com.auth0.models.AuthToken("token", "proof", null) ); - when(jwtValidator.validateToken(eq("token"), any())).thenReturn(jwt); + when(jwtValidator.validateToken(eq("token"), anyMap(), any())).thenReturn(jwt); Map headers = new HashMap<>(); headers.put("authorization", "DPoP token"); diff --git a/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java b/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java index 2ec5d48..2337c16 100644 --- a/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java +++ b/auth0-api-java/src/test/java/com/auth0/validators/JWTValidatorTest.java @@ -19,6 +19,7 @@ import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Date; +import java.util.HashMap; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; @@ -80,7 +81,7 @@ public void constructor_shouldRejectNullJwkProvider() { public void validateToken_success() throws Exception { String token = validToken(); - DecodedJWT jwt = validator.validateToken(token, null); + DecodedJWT jwt = validator.validateToken(token, null, null); assertThat(jwt.getIssuer()).isEqualTo(ISSUER); assertThat(jwt.getAudience()).contains(AUDIENCE); @@ -89,7 +90,7 @@ public void validateToken_success() throws Exception { @Test(expected = MissingRequiredArgumentException.class) public void validateToken_shouldRejectNullToken() throws Exception { - validator.validateToken(null, null); + validator.validateToken(null, null, null); } @Test(expected = VerifyAccessTokenException.class) @@ -100,14 +101,14 @@ public void validateToken_shouldRejectInvalidSignature() throws Exception { when(jwk.getPublicKey()).thenReturn(wrongKey); - validator.validateToken(validToken(), null); + validator.validateToken(validToken(), null, null); } @Test public void validateTokenWithRequiredScopes_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithRequiredScopes(token, null, "read"); + DecodedJWT jwt = validator.validateTokenWithRequiredScopes(token, new HashMap<>(), null, "read"); assertThat(jwt).isNotNull(); } @@ -116,14 +117,14 @@ public void validateTokenWithRequiredScopes_success() throws Exception { public void validateTokenWithRequiredScopes_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithRequiredScopes(token, null, "admin"); + validator.validateTokenWithRequiredScopes(token, new HashMap<>(), null, "admin"); } @Test public void validateTokenWithAnyScope_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithAnyScope(token, null, "admin", "write"); + DecodedJWT jwt = validator.validateTokenWithAnyScope(token, new HashMap<>(), null, "admin", "write"); assertThat(jwt).isNotNull(); } @@ -132,14 +133,14 @@ public void validateTokenWithAnyScope_success() throws Exception { public void validateTokenWithAnyScope_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithAnyScope(token, null, "admin"); + validator.validateTokenWithAnyScope(token, new HashMap<>(), null, "admin"); } @Test public void validateTokenWithClaimEquals_success() throws Exception { String token = tokenWithEmail("a@b.com"); - DecodedJWT jwt = validator.validateTokenWithClaimEquals(token, null, "email", "a@b.com"); + DecodedJWT jwt = validator.validateTokenWithClaimEquals(token, new HashMap<>(), null, "email", "a@b.com"); assertThat(jwt).isNotNull(); } @@ -148,14 +149,14 @@ public void validateTokenWithClaimEquals_success() throws Exception { public void validateTokenWithClaimEquals_failure() throws Exception { String token = tokenWithEmail("a@b.com"); - validator.validateTokenWithClaimEquals(token, null, "email", "x@y.com"); + validator.validateTokenWithClaimEquals(token, new HashMap<>(), null, "email", "x@y.com"); } @Test public void validateTokenWithClaimIncludes_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithClaimIncludes(token, null, "scope", "read"); + DecodedJWT jwt = validator.validateTokenWithClaimIncludes(token, new HashMap<>(), null, "scope", "read"); assertThat(jwt).isNotNull(); } @@ -164,14 +165,14 @@ public void validateTokenWithClaimIncludes_success() throws Exception { public void validateTokenWithClaimIncludes_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithClaimIncludes(token, null, "scope", "admin"); + validator.validateTokenWithClaimIncludes(token, new HashMap<>(), null, "scope", "admin"); } @Test public void validateTokenWithClaimIncludesAny_success() throws Exception { String token = tokenWithScopes("read write"); - DecodedJWT jwt = validator.validateTokenWithClaimIncludesAny(token, null, "scope", "admin", "write"); + DecodedJWT jwt = validator.validateTokenWithClaimIncludesAny(token, new HashMap<>(), null, "scope", "admin", "write"); assertThat(jwt).isNotNull(); } @@ -180,7 +181,7 @@ public void validateTokenWithClaimIncludesAny_success() throws Exception { public void validateTokenWithClaimIncludesAny_failure() throws Exception { String token = tokenWithScopes("read"); - validator.validateTokenWithClaimIncludesAny(token, null, "scope", "admin"); + validator.validateTokenWithClaimIncludesAny(token, new HashMap<>(), null, "scope", "admin"); } @Test From 881c21f2fecbb41aa6f366bb127b7366064f46c6 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Thu, 19 Feb 2026 15:33:39 +0530 Subject: [PATCH 3/3] Updated to ubuntu-latest --- .github/workflows/build-and-test.yml | 2 +- .github/workflows/claude-code-review.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 3655697..fbc6433 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -8,7 +8,7 @@ on: jobs: gradle: - runs-on: ubuntu-22.04-2cpu-8ram-75ssd + runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-java@v5 diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 2ba886f..673cab1 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -8,4 +8,4 @@ on: jobs: claude-review: - uses: atko-cic/ai-pr-analyzer-gh-action/.github/workflows/claude-code-review.yml@main \ No newline at end of file + uses: auth0/ai-pr-analyzer-gh-action/.github/workflows/claude-code-review.yml@main \ No newline at end of file