Skip to content

Commit 57e1346

Browse files
authored
M2M JWT support (#395)
Custom client credential support
1 parent 19117b8 commit 57e1346

18 files changed

+823
-12
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ target/
44
*DS_Store
55
TestFile
66
logs/
7-
*.log
7+
*.log
8+
*.pem

pom.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
<slt.executor>dbsql</slt.executor>
6262
<slt.token>dummy-token</slt.token>
6363
<wiremock.version>3.5.4</wiremock.version>
64+
<nimbusjose.version>9.40</nimbusjose.version>
65+
<bouncycastle.version>1.78.1</bouncycastle.version>
6466
</properties>
6567
<dependencies>
6668
<dependency>
@@ -142,6 +144,22 @@
142144
<version>${junit.jupiter.version}</version>
143145
<scope>test</scope>
144146
</dependency>
147+
148+
<dependency>
149+
<groupId>com.nimbusds</groupId>
150+
<artifactId>nimbus-jose-jwt</artifactId>
151+
<version>${nimbusjose.version}</version>
152+
</dependency>
153+
<dependency>
154+
<groupId>org.bouncycastle</groupId>
155+
<artifactId>bcprov-jdk18on</artifactId>
156+
<version>${bouncycastle.version}</version>
157+
</dependency>
158+
<dependency>
159+
<groupId>org.bouncycastle</groupId>
160+
<artifactId>bcpkix-jdk18on</artifactId>
161+
<version>${bouncycastle.version}</version>
162+
</dependency>
145163
<dependency>
146164
<groupId>org.mockito</groupId>
147165
<artifactId>mockito-inline</artifactId>
@@ -521,4 +539,4 @@
521539
</build>
522540
</profile>
523541
</profiles>
524-
</project>
542+
</project>

src/main/java/com/databricks/jdbc/api/IDatabricksConnectionContext.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,34 @@ public static AuthMech parseAuthMech(String authMech) {
152152
boolean enableTelemetry();
153153

154154
String getConnectionURL();
155+
156+
/** Returns the file path to the JWT private key used for signing the JWT. */
157+
String getJWTKeyFile();
158+
159+
/** Returns the Key ID (KID) used in the JWT header, identifying the key. */
160+
String getKID();
161+
162+
/** Returns the passphrase to decrypt the private key if the key is encrypted. */
163+
String getJWTPassphrase();
164+
165+
/** Returns the algorithm used for signing the JWT (e.g., RS256, ES256). */
166+
String getJWTAlgorithm();
167+
168+
/** Returns whether JWT assertion should be used for OAuth2 authentication. */
169+
boolean useJWTAssertion();
170+
171+
/** Returns the OAuth2 token endpoint URL for retrieving tokens. */
172+
String getTokenEndpoint();
173+
174+
/** Returns the OAuth2 authorization endpoint URL for the authorization code flow. */
175+
String getAuthEndpoint();
176+
177+
/** Returns whether OAuth2 discovery mode is enabled, which fetches endpoints dynamically. */
178+
boolean isOAuthDiscoveryModeEnabled();
179+
180+
/** Returns the discovery URL used to obtain the OAuth2 token and authorization endpoints. */
181+
String getOAuthDiscoveryURL();
182+
183+
/** Returns the OAuth2 authentication scope used in the request. */
184+
String getAuthScope();
155185
}

src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,4 +568,54 @@ public boolean enableTelemetry() {
568568
public String getConnectionURL() {
569569
return connectionURL;
570570
}
571+
572+
@Override
573+
public String getJWTKeyFile() {
574+
return getParameter(JWT_KEY_FILE);
575+
}
576+
577+
@Override
578+
public String getKID() {
579+
return getParameter(JWT_KID);
580+
}
581+
582+
@Override
583+
public String getJWTPassphrase() {
584+
return getParameter(JWT_PASS_PHRASE);
585+
}
586+
587+
@Override
588+
public String getJWTAlgorithm() {
589+
return getParameter(JWT_ALGORITHM);
590+
}
591+
592+
@Override
593+
public boolean useJWTAssertion() {
594+
return getParameter(USE_JWT_ASSERTION, "0").equals("1");
595+
}
596+
597+
@Override
598+
public String getTokenEndpoint() {
599+
return getParameter(TOKEN_ENDPOINT);
600+
}
601+
602+
@Override
603+
public String getAuthEndpoint() {
604+
return getParameter(AUTH_ENDPOINT);
605+
}
606+
607+
@Override
608+
public boolean isOAuthDiscoveryModeEnabled() {
609+
return getParameter(DISCOVERY_MODE, "1").equals("1");
610+
}
611+
612+
@Override
613+
public String getOAuthDiscoveryURL() {
614+
return getParameter(DISCOVERY_URL);
615+
}
616+
617+
@Override
618+
public String getAuthScope() {
619+
return getParameter(AUTH_SCOPE, ALL_APIS_SCOPE);
620+
}
571621
}

src/main/java/com/databricks/jdbc/dbclient/impl/common/ClientUtils.java renamed to src/main/java/com/databricks/jdbc/auth/ClientUtils.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
package com.databricks.jdbc.dbclient.impl.common;
1+
package com.databricks.jdbc.auth;
22

33
import com.databricks.jdbc.api.IDatabricksConnectionContext;
4-
import com.databricks.jdbc.exception.DatabricksParsingException;
54
import com.databricks.sdk.core.DatabricksConfig;
65

76
public class ClientUtils {
87
public static DatabricksConfig generateDatabricksConfig(
9-
IDatabricksConnectionContext connectionContext) throws DatabricksParsingException {
8+
IDatabricksConnectionContext connectionContext) {
109
DatabricksConfig databricksConfig =
1110
new DatabricksConfig().setUseSystemPropertiesHttp(connectionContext.getUseSystemProxy());
1211
// Setup proxy settings

0 commit comments

Comments
 (0)