From dd6a9e789ad0f7b13770dfcac10d281ad547b043 Mon Sep 17 00:00:00 2001 From: Wes Tarle Date: Mon, 15 Jun 2026 12:42:58 +0000 Subject: [PATCH] test(auth): Assert JWT headers and claims (alg, typ, iat, exp) This commit adds explicit assertions to verify that the generated JWS header correctly contains 'alg=RS256' and 'typ=JWT', and that the JWT payload contains the 'iat' and 'exp' claims with exactly a 3600-second (1-hour) expiration offset. This brings the Java library's test suite into alignment with the expected auth specification. Other Google Cloud client libraries like Go, Node.js, and Python natively assert the presence of these standard headers and the 1-hour expiration window during their Self-Signed JWT generation tests. --- .../auth/oauth2/ServiceAccountCredentialsTest.java | 10 ++++++++++ .../oauth2/ServiceAccountJwtAccessCredentialsTest.java | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java index ed26a0af3c6f..1bae2651f5ab 100644 --- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java +++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java @@ -1777,6 +1777,8 @@ private void verifyJwtAccess(Map> metadata, String expected assertNotNull(assertion, "Bearer assertion not found"); JsonWebSignature signature = JsonWebSignature.parse(GsonFactory.getDefaultInstance(), assertion); + assertEquals("RS256", signature.getHeader().getAlgorithm()); + assertEquals("JWT", signature.getHeader().getType()); assertEquals(CLIENT_EMAIL, signature.getPayload().getIssuer()); assertEquals(CLIENT_EMAIL, signature.getPayload().getSubject()); if (expectedScopeClaim != null) { @@ -1787,6 +1789,14 @@ private void verifyJwtAccess(Map> metadata, String expected assertFalse(signature.getPayload().containsKey("scope")); } assertEquals(PRIVATE_KEY_ID, signature.getHeader().getKeyId()); + + Long iat = signature.getPayload().getIssuedAtTimeSeconds(); + Long exp = signature.getPayload().getExpirationTimeSeconds(); + assertNotNull(iat); + assertNotNull(exp); + assertEquals(3600L, exp - iat); + long currentTimeSecs = System.currentTimeMillis() / 1000; + assertTrue(Math.abs(currentTimeSecs - iat) < 60); } static GenericJson writeServiceAccountJson( diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index d961f7b1b685..4a12b7483a33 100644 --- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -914,6 +914,8 @@ private void verifyJwtAccess(Map> metadata, URI expectedAud } assertNotNull(assertion, "Bearer assertion not found"); JsonWebSignature signature = JsonWebSignature.parse(JSON_FACTORY, assertion); + assertEquals("RS256", signature.getHeader().getAlgorithm()); + assertEquals("JWT", signature.getHeader().getType()); assertEquals( ServiceAccountJwtAccessCredentialsTest.SA_CLIENT_EMAIL, signature.getPayload().getIssuer()); assertEquals( @@ -922,6 +924,14 @@ private void verifyJwtAccess(Map> metadata, URI expectedAud assertEquals(expectedAudience.toString(), signature.getPayload().getAudience()); assertEquals( ServiceAccountJwtAccessCredentialsTest.SA_PRIVATE_KEY_ID, signature.getHeader().getKeyId()); + + Long iat = signature.getPayload().getIssuedAtTimeSeconds(); + Long exp = signature.getPayload().getExpirationTimeSeconds(); + assertNotNull(iat); + assertNotNull(exp); + assertEquals(3600L, exp - iat); + long currentTimeSecs = System.currentTimeMillis() / 1000; + assertTrue(Math.abs(currentTimeSecs - iat) < 60); } private static void testFromStreamException(InputStream stream, String expectedMessageContent) {