From 62995108f5c6ecade1e11d038dbb3de5a7bc499a Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 30 Apr 2026 09:56:10 -0400 Subject: [PATCH 1/7] fix(bqjdbc): support Service Account Impersonation in ADC --- .../jdbc/BigQueryJdbcOAuthUtility.java | 5 ++- .../jdbc/BigQueryJdbcOAuthUtilityTest.java | 33 +++++++++++++++++++ .../cloud/bigquery/jdbc/it/ITAuthTests.java | 11 +++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java b/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java index f49f503a6dec..6b17f1f19c2f 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java @@ -232,7 +232,8 @@ static Map parseOAuthProperties(DataSource ds, String callerClas if (authType == AuthType.GOOGLE_SERVICE_ACCOUNT || authType == AuthType.GOOGLE_USER_ACCOUNT - || authType == AuthType.PRE_GENERATED_TOKEN) { + || authType == AuthType.PRE_GENERATED_TOKEN + || authType == AuthType.APPLICATION_DEFAULT_CREDENTIALS) { oauthProperties.put( BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_EMAIL_PROPERTY_NAME, ds.getOAuthSAImpersonationEmail()); @@ -284,8 +285,6 @@ static GoogleCredentials getCredentials( getPreGeneratedTokensCredentials(authProperties, overrideProperties, callerClassName); break; case APPLICATION_DEFAULT_CREDENTIALS: - // This auth method doesn't support service account impersonation - credentials = getApplicationDefaultCredentials(callerClassName); break; case EXTERNAL_ACCOUNT_AUTH: diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java index 9176bb83d7be..a7cf02d4f7b2 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java @@ -377,6 +377,39 @@ public void testParseUserImpersonationNonDefault() { result.get(BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_TOKEN_LIFETIME_PROPERTY_NAME)); } + @Test + public void testParseUserImpersonationForADC() { + Map result = + BigQueryJdbcOAuthUtility.parseOAuthProperties( + DataSource.fromUrl( + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;ProjectId=MyBigQueryProject;" + + "ServiceAccountImpersonationEmail=impersonated@email.com;"), + ""); + + assertEquals("APPLICATION_DEFAULT_CREDENTIALS", result.get("OAuthType")); + assertEquals( + "impersonated@email.com", + result.get(BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_EMAIL_PROPERTY_NAME)); + } + + @Test + public void testGetServiceAccountImpersonatedCredentialsForADC() { + Map authProperties = + BigQueryJdbcOAuthUtility.parseOAuthProperties( + DataSource.fromUrl( + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;ProjectId=MyBigQueryProject;" + + "ServiceAccountImpersonationEmail=impersonated@email.com;"), + ""); + + GoogleCredentials credentials = + BigQueryJdbcOAuthUtility.getCredentials( + authProperties, java.util.Collections.EMPTY_MAP, false, null); + + assertThat(credentials).isInstanceOf(ImpersonatedCredentials.class); + } + @Test public void testGetServiceAccountImpersonatedCredentials() { Map authProperties = diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/it/ITAuthTests.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/it/ITAuthTests.java index f57493a997de..0fcb30903b25 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/it/ITAuthTests.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/it/ITAuthTests.java @@ -371,4 +371,15 @@ public void testServiceAccountAuthenticationWithChainedImpersonation() .toString(); validateConnection(connection_uri); } + + @Test + public void testADCAuthenticationWithImpersonation() throws IOException, SQLException { + final JsonObject authJson = getAuthJson(); + + String connection_uri = + getBaseUri(3, authJson.get("project_id").getAsString()) + .append("ServiceAccountImpersonationEmail", authJson.get("client_email").getAsString()) + .toString(); + validateConnection(connection_uri); + } } From c2e7e89afe16871cc5fd7205d8999ca980676f04 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 30 Apr 2026 10:19:43 -0400 Subject: [PATCH 2/7] disable local test --- .../cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java index a7cf02d4f7b2..29be448e6e67 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java @@ -394,6 +394,7 @@ public void testParseUserImpersonationForADC() { } @Test + @Disabled public void testGetServiceAccountImpersonatedCredentialsForADC() { Map authProperties = BigQueryJdbcOAuthUtility.parseOAuthProperties( @@ -404,8 +405,7 @@ public void testGetServiceAccountImpersonatedCredentialsForADC() { ""); GoogleCredentials credentials = - BigQueryJdbcOAuthUtility.getCredentials( - authProperties, java.util.Collections.EMPTY_MAP, false, null); + BigQueryJdbcOAuthUtility.getCredentials(authProperties, null, false, null); assertThat(credentials).isInstanceOf(ImpersonatedCredentials.class); } From 331a77d75170fc5d5aa0579acfb18aa89f8f8183 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 30 Apr 2026 12:07:02 -0400 Subject: [PATCH 3/7] add local test --- .../jdbc/BigQueryJdbcOAuthUtilityTest.java | 61 +++++++++++++++---- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java index 29be448e6e67..e4098c245f41 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java @@ -394,20 +394,57 @@ public void testParseUserImpersonationForADC() { } @Test - @Disabled - public void testGetServiceAccountImpersonatedCredentialsForADC() { - Map authProperties = - BigQueryJdbcOAuthUtility.parseOAuthProperties( - DataSource.fromUrl( - "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" - + "OAuthType=3;ProjectId=MyBigQueryProject;" - + "ServiceAccountImpersonationEmail=impersonated@email.com;"), - ""); + public void testGetServiceAccountImpersonatedCredentialsForADC() throws Exception { + String dummyJson = + "{\n" + + " \"type\": \"service_account\",\n" + + " \"project_id\": \"dummy-project\",\n" + + " \"private_key_id\": \"dummy-key-id\",\n" + + " \"private_key\": \"" + + fake_pkcs8_key.replace("\n", "\\n") + + "\",\n" + + " \"client_email\": \"dummy@email.com\",\n" + + " \"client_id\": \"dummy-client-id\",\n" + + " \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n" + + " \"token_uri\": \"https://oauth2.googleapis.com/token\"\n" + + "}"; + + java.nio.file.Path tempFile = java.nio.file.Files.createTempFile("adc", ".json"); + java.nio.file.Files.write(tempFile, dummyJson.getBytes()); + tempFile.toFile().deleteOnExit(); + + Class processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment"); + java.lang.reflect.Field theEnvironmentField = + processEnvironmentClass.getDeclaredField("theEnvironment"); + theEnvironmentField.setAccessible(true); + java.util.Map env = + (java.util.Map) theEnvironmentField.get(null); + + String originalEnv = env.get("GOOGLE_APPLICATION_CREDENTIALS"); - GoogleCredentials credentials = - BigQueryJdbcOAuthUtility.getCredentials(authProperties, null, false, null); + try { + if (originalEnv == null) { + env.put("GOOGLE_APPLICATION_CREDENTIALS", tempFile.toAbsolutePath().toString()); + } - assertThat(credentials).isInstanceOf(ImpersonatedCredentials.class); + Map authProperties = + BigQueryJdbcOAuthUtility.parseOAuthProperties( + DataSource.fromUrl( + "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;" + + "OAuthType=3;ProjectId=MyBigQueryProject;" + + "ServiceAccountImpersonationEmail=impersonated@email.com;"), + ""); + + GoogleCredentials credentials = + BigQueryJdbcOAuthUtility.getCredentials( + authProperties, java.util.Collections.EMPTY_MAP, false, null); + + assertThat(credentials).isInstanceOf(ImpersonatedCredentials.class); + } finally { + if (originalEnv == null) { + env.remove("GOOGLE_APPLICATION_CREDENTIALS"); + } + } } @Test From 70a819f4f7c956ae823a1774ddda8daa4db617bf Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 30 Apr 2026 12:28:17 -0400 Subject: [PATCH 4/7] chore: fix test --- .../jdbc/BigQueryJdbcOAuthUtilityTest.java | 87 +++++++++++++------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java index e4098c245f41..6030eea1649b 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java @@ -395,36 +395,14 @@ public void testParseUserImpersonationForADC() { @Test public void testGetServiceAccountImpersonatedCredentialsForADC() throws Exception { - String dummyJson = - "{\n" - + " \"type\": \"service_account\",\n" - + " \"project_id\": \"dummy-project\",\n" - + " \"private_key_id\": \"dummy-key-id\",\n" - + " \"private_key\": \"" - + fake_pkcs8_key.replace("\n", "\\n") - + "\",\n" - + " \"client_email\": \"dummy@email.com\",\n" - + " \"client_id\": \"dummy-client-id\",\n" - + " \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n" - + " \"token_uri\": \"https://oauth2.googleapis.com/token\"\n" - + "}"; - - java.nio.file.Path tempFile = java.nio.file.Files.createTempFile("adc", ".json"); - java.nio.file.Files.write(tempFile, dummyJson.getBytes()); - tempFile.toFile().deleteOnExit(); - - Class processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment"); - java.lang.reflect.Field theEnvironmentField = - processEnvironmentClass.getDeclaredField("theEnvironment"); - theEnvironmentField.setAccessible(true); - java.util.Map env = - (java.util.Map) theEnvironmentField.get(null); - - String originalEnv = env.get("GOOGLE_APPLICATION_CREDENTIALS"); + java.nio.file.Path tempAdcFile = createTempAdcFile(); + String originalEnv = System.getenv("GOOGLE_APPLICATION_CREDENTIALS"); try { if (originalEnv == null) { - env.put("GOOGLE_APPLICATION_CREDENTIALS", tempFile.toAbsolutePath().toString()); + setEnvironmentVariable( + "GOOGLE_APPLICATION_CREDENTIALS", tempAdcFile.toAbsolutePath().toString()); + clearDefaultCredentialsCache(); } Map authProperties = @@ -442,7 +420,8 @@ public void testGetServiceAccountImpersonatedCredentialsForADC() throws Exceptio assertThat(credentials).isInstanceOf(ImpersonatedCredentials.class); } finally { if (originalEnv == null) { - env.remove("GOOGLE_APPLICATION_CREDENTIALS"); + removeEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"); + clearDefaultCredentialsCache(); } } } @@ -501,4 +480,56 @@ public void testPrivateKeyFromP12Bytes_wrong_password() { assertTrue(false); } } + + private static java.nio.file.Path createTempAdcFile() throws Exception { + String dummyJson = + "{\n" + + " \"type\": \"service_account\",\n" + + " \"project_id\": \"dummy-project\",\n" + + " \"private_key_id\": \"dummy-key-id\",\n" + + " \"private_key\": \"" + + fake_pkcs8_key.replace("\n", "\\n") + + "\",\n" + + " \"client_email\": \"dummy@email.com\",\n" + + " \"client_id\": \"dummy-client-id\",\n" + + " \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n" + + " \"token_uri\": \"https://oauth2.googleapis.com/token\"\n" + + "}"; + + java.nio.file.Path tempFile = java.nio.file.Files.createTempFile("adc", ".json"); + java.nio.file.Files.write(tempFile, dummyJson.getBytes()); + tempFile.toFile().deleteOnExit(); + return tempFile; + } + + private static void setEnvironmentVariable(String key, String value) throws Exception { + Class processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment"); + java.lang.reflect.Field theEnvironmentField = + processEnvironmentClass.getDeclaredField("theEnvironment"); + theEnvironmentField.setAccessible(true); + java.util.Map env = + (java.util.Map) theEnvironmentField.get(null); + env.put(key, value); + } + + private static void removeEnvironmentVariable(String key) throws Exception { + Class processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment"); + java.lang.reflect.Field theEnvironmentField = + processEnvironmentClass.getDeclaredField("theEnvironment"); + theEnvironmentField.setAccessible(true); + java.util.Map env = + (java.util.Map) theEnvironmentField.get(null); + env.remove(key); + } + + private static void clearDefaultCredentialsCache() throws Exception { + Class providerClass = Class.forName("com.google.auth.oauth2.DefaultCredentialsProvider"); + java.lang.reflect.Field defaultField = providerClass.getDeclaredField("DEFAULT"); + defaultField.setAccessible(true); + Object provider = defaultField.get(null); + + java.lang.reflect.Field cachedCredsField = providerClass.getDeclaredField("cachedCredentials"); + cachedCredsField.setAccessible(true); + cachedCredsField.set(provider, null); + } } From b345e1f7ef6d76c045a90fbc36496cedbfa9a579 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 30 Apr 2026 12:50:24 -0400 Subject: [PATCH 5/7] fix test --- .../google-cloud-bigquery-jdbc/pom.xml | 5 ++ .../jdbc/BigQueryCallableStatementTest.java | 6 +- .../jdbc/BigQueryJdbcOAuthUtilityTest.java | 69 ++----------------- 3 files changed, 12 insertions(+), 68 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/pom.xml b/java-bigquery/google-cloud-bigquery-jdbc/pom.xml index 9ebe4576026c..fea7c3c1c5be 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/pom.xml +++ b/java-bigquery/google-cloud-bigquery-jdbc/pom.xml @@ -307,6 +307,11 @@ mockito-core test + + org.mockito + mockito-inline + test + org.mockito mockito-junit-jupiter diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryCallableStatementTest.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryCallableStatementTest.java index a1d7c053655c..c873e4cef970 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryCallableStatementTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryCallableStatementTest.java @@ -914,7 +914,7 @@ public void testSetDateCalParamByName() throws SQLException { Calendar expectedCal = mock(Calendar.class); doReturn(1L).when(expectedDate).getTime(); - doReturn(1L).when(expectedCal).getTime(); + doReturn(new java.util.Date(1L)).when(expectedCal).getTime(); doReturn(1L).when(expectedCal).getTimeInMillis(); statement.setDate(PARAM_KEY, expectedDate, expectedCal); Date actual = statement.getDate(PARAM_KEY); @@ -1033,7 +1033,7 @@ public void testSetTimeCalParamByName() throws SQLException { Calendar expectedCal = mock(Calendar.class); doReturn(1L).when(expectedTime).getTime(); - doReturn(1L).when(expectedCal).getTime(); + doReturn(new java.util.Date(1L)).when(expectedCal).getTime(); doReturn(1L).when(expectedCal).getTimeInMillis(); statement.setTime(PARAM_KEY, expectedTime, expectedCal); Time actual = statement.getTime(PARAM_KEY); @@ -1062,7 +1062,7 @@ public void testSetTimestampCalParamByName() throws SQLException { Calendar expectedCal = mock(Calendar.class); doReturn(1L).when(expectedTimestamp).getTime(); - doReturn(1L).when(expectedCal).getTime(); + doReturn(new java.util.Date(1L)).when(expectedCal).getTime(); doReturn(1L).when(expectedCal).getTimeInMillis(); statement.setTimestamp(PARAM_KEY, expectedTimestamp, expectedCal); Timestamp actual = statement.getTimestamp(PARAM_KEY); diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java index 6030eea1649b..f0cfaf150c0c 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java @@ -395,15 +395,11 @@ public void testParseUserImpersonationForADC() { @Test public void testGetServiceAccountImpersonatedCredentialsForADC() throws Exception { - java.nio.file.Path tempAdcFile = createTempAdcFile(); - String originalEnv = System.getenv("GOOGLE_APPLICATION_CREDENTIALS"); + GoogleCredentials dummySourceCredentials = GoogleCredentials.newBuilder().build(); - try { - if (originalEnv == null) { - setEnvironmentVariable( - "GOOGLE_APPLICATION_CREDENTIALS", tempAdcFile.toAbsolutePath().toString()); - clearDefaultCredentialsCache(); - } + try (org.mockito.MockedStatic mockedCreds = + org.mockito.Mockito.mockStatic(GoogleCredentials.class)) { + mockedCreds.when(GoogleCredentials::getApplicationDefault).thenReturn(dummySourceCredentials); Map authProperties = BigQueryJdbcOAuthUtility.parseOAuthProperties( @@ -418,11 +414,6 @@ public void testGetServiceAccountImpersonatedCredentialsForADC() throws Exceptio authProperties, java.util.Collections.EMPTY_MAP, false, null); assertThat(credentials).isInstanceOf(ImpersonatedCredentials.class); - } finally { - if (originalEnv == null) { - removeEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"); - clearDefaultCredentialsCache(); - } } } @@ -480,56 +471,4 @@ public void testPrivateKeyFromP12Bytes_wrong_password() { assertTrue(false); } } - - private static java.nio.file.Path createTempAdcFile() throws Exception { - String dummyJson = - "{\n" - + " \"type\": \"service_account\",\n" - + " \"project_id\": \"dummy-project\",\n" - + " \"private_key_id\": \"dummy-key-id\",\n" - + " \"private_key\": \"" - + fake_pkcs8_key.replace("\n", "\\n") - + "\",\n" - + " \"client_email\": \"dummy@email.com\",\n" - + " \"client_id\": \"dummy-client-id\",\n" - + " \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n" - + " \"token_uri\": \"https://oauth2.googleapis.com/token\"\n" - + "}"; - - java.nio.file.Path tempFile = java.nio.file.Files.createTempFile("adc", ".json"); - java.nio.file.Files.write(tempFile, dummyJson.getBytes()); - tempFile.toFile().deleteOnExit(); - return tempFile; - } - - private static void setEnvironmentVariable(String key, String value) throws Exception { - Class processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment"); - java.lang.reflect.Field theEnvironmentField = - processEnvironmentClass.getDeclaredField("theEnvironment"); - theEnvironmentField.setAccessible(true); - java.util.Map env = - (java.util.Map) theEnvironmentField.get(null); - env.put(key, value); - } - - private static void removeEnvironmentVariable(String key) throws Exception { - Class processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment"); - java.lang.reflect.Field theEnvironmentField = - processEnvironmentClass.getDeclaredField("theEnvironment"); - theEnvironmentField.setAccessible(true); - java.util.Map env = - (java.util.Map) theEnvironmentField.get(null); - env.remove(key); - } - - private static void clearDefaultCredentialsCache() throws Exception { - Class providerClass = Class.forName("com.google.auth.oauth2.DefaultCredentialsProvider"); - java.lang.reflect.Field defaultField = providerClass.getDeclaredField("DEFAULT"); - defaultField.setAccessible(true); - Object provider = defaultField.get(null); - - java.lang.reflect.Field cachedCredsField = providerClass.getDeclaredField("cachedCredentials"); - cachedCredsField.setAccessible(true); - cachedCredsField.set(provider, null); - } } From 191b05b8c27b2af9b1c2bc57fe9ee359bf7ea291 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 30 Apr 2026 12:58:49 -0400 Subject: [PATCH 6/7] verify correct source --- .../cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java index f0cfaf150c0c..adb7526cf6a5 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtilityTest.java @@ -414,6 +414,8 @@ public void testGetServiceAccountImpersonatedCredentialsForADC() throws Exceptio authProperties, java.util.Collections.EMPTY_MAP, false, null); assertThat(credentials).isInstanceOf(ImpersonatedCredentials.class); + assertThat(((ImpersonatedCredentials) credentials).getSourceCredentials()) + .isEqualTo(dummySourceCredentials); } } From fd8f6c59cad57db67b5e5d5003950a1e630ea63c Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Fri, 1 May 2026 09:49:59 -0400 Subject: [PATCH 7/7] support impersonation for all types --- .../jdbc/BigQueryJdbcOAuthUtility.java | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java b/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java index 6b17f1f19c2f..ce39f2c7aba5 100644 --- a/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java +++ b/java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcOAuthUtility.java @@ -230,27 +230,22 @@ static Map parseOAuthProperties(DataSource ds, String callerClas break; } - if (authType == AuthType.GOOGLE_SERVICE_ACCOUNT - || authType == AuthType.GOOGLE_USER_ACCOUNT - || authType == AuthType.PRE_GENERATED_TOKEN - || authType == AuthType.APPLICATION_DEFAULT_CREDENTIALS) { - oauthProperties.put( - BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_EMAIL_PROPERTY_NAME, - ds.getOAuthSAImpersonationEmail()); - oauthProperties.put( - BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_CHAIN_PROPERTY_NAME, - ds.getOAuthSAImpersonationChain()); - oauthProperties.put( - BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_SCOPES_PROPERTY_NAME, - ds.getOAuthSAImpersonationScopes() != null - ? ds.getOAuthSAImpersonationScopes() - : BIGQUERY_SCOPE); - oauthProperties.put( - BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_TOKEN_LIFETIME_PROPERTY_NAME, - ds.getOAuthSAImpersonationTokenLifetime() != null - ? ds.getOAuthSAImpersonationTokenLifetime() - : BigQueryJdbcUrlUtility.DEFAULT_OAUTH_SA_IMPERSONATION_TOKEN_LIFETIME_VALUE); - } + oauthProperties.put( + BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_EMAIL_PROPERTY_NAME, + ds.getOAuthSAImpersonationEmail()); + oauthProperties.put( + BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_CHAIN_PROPERTY_NAME, + ds.getOAuthSAImpersonationChain()); + oauthProperties.put( + BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_SCOPES_PROPERTY_NAME, + ds.getOAuthSAImpersonationScopes() != null + ? ds.getOAuthSAImpersonationScopes() + : BIGQUERY_SCOPE); + oauthProperties.put( + BigQueryJdbcUrlUtility.OAUTH_SA_IMPERSONATION_TOKEN_LIFETIME_PROPERTY_NAME, + ds.getOAuthSAImpersonationTokenLifetime() != null + ? ds.getOAuthSAImpersonationTokenLifetime() + : BigQueryJdbcUrlUtility.DEFAULT_OAUTH_SA_IMPERSONATION_TOKEN_LIFETIME_VALUE); return oauthProperties; } @@ -288,7 +283,6 @@ static GoogleCredentials getCredentials( credentials = getApplicationDefaultCredentials(callerClassName); break; case EXTERNAL_ACCOUNT_AUTH: - // This auth method doesn't support service account impersonation credentials = getExternalAccountAuthCredentials(authProperties, callerClassName); break; default: