diff --git a/aep-service/src/main/java/foundation/aep/service/AepService.java b/aep-service/src/main/java/foundation/aep/service/AepService.java index 4a23c3c..c14b479 100644 --- a/aep-service/src/main/java/foundation/aep/service/AepService.java +++ b/aep-service/src/main/java/foundation/aep/service/AepService.java @@ -336,7 +336,7 @@ private boolean validClaims(ClientAssertionClaims claims, AssertionOperation ope try { Instant issued = Instant.ofEpochSecond(claims.issuedAt()); Instant expires = Instant.ofEpochSecond(claims.expiresAt()); - return !issued.isAfter(now.plus(clockSkew)) && !expires.isBefore(now.minus(clockSkew)); + return !issued.isAfter(now.plus(clockSkew)) && expires.isAfter(now.minus(clockSkew)); } catch (RuntimeException exception) { return false; } diff --git a/aep-service/src/test/java/foundation/aep/service/AepServiceTest.java b/aep-service/src/test/java/foundation/aep/service/AepServiceTest.java index bde3563..e61d488 100644 --- a/aep-service/src/test/java/foundation/aep/service/AepServiceTest.java +++ b/aep-service/src/test/java/foundation/aep/service/AepServiceTest.java @@ -97,6 +97,31 @@ void rejectsReplayedAssertionWithoutDisclosingTheCause() { assertEquals("not_recognized", second.problem().code()); } + @Test + void rejectsExpirationBoundaryFromCustomVerifier() { + AepService service = AepService.builder( + document(false), + (assertion, context) -> completed(new ClientAssertionClaims( + AGENT_DID, + AGENT_DID, + context.serviceDid(), + context.operation(), + NOW.minusSeconds(60).getEpochSecond(), + NOW.minusSeconds(30).getEpochSecond(), + "expiration-boundary", + null))) + .clock(Clock.fixed(NOW, ZoneOffset.UTC)) + .clockSkew(java.time.Duration.ofSeconds(30)) + .build(); + + ServiceResponse response = service.status(CommandOptions.authenticated("assertion")) + .toCompletableFuture() + .join(); + + assertEquals(401, response.status()); + assertEquals("not_recognized", response.problem().code()); + } + @Test void grantsAndRevokesThroughTheAdvertisedHandler() { RecordingGrantHandler handler = new RecordingGrantHandler();