-
Notifications
You must be signed in to change notification settings - Fork 27
[PECOBLR-131][PECOBLR-180] Add token cache for U2M OAuth #768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds token cache support for U2M OAuth in the JDBC driver. The changes include:
- Introducing a new TokenCache implementation with encryption to persist tokens.
- Adding comprehensive tests for token caching behavior and the caching credentials provider.
- Updating configuration classes and URL parameters to support the new TokenCachePassPhrase parameter.
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/com/databricks/jdbc/dbclient/impl/common/ClientConfiguratorTest.java | Added tests verifying behavior with a valid passphrase and error handling when missing. |
| src/test/java/com/databricks/jdbc/auth/TokenCacheTest.java | New tests for saving, loading, and error conditions in token caching. |
| src/test/java/com/databricks/jdbc/auth/CachingExternalBrowserCredentialsProviderTest.java | New tests to verify both the token refresh and browser authentication fallback logic. |
| src/main/java/com/databricks/jdbc/dbclient/impl/common/ClientConfigurator.java | Modified to use the caching credentials provider for U2M OAuth. |
| src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java | Added a new URL parameter for TokenCachePassPhrase. |
| src/main/java/com/databricks/jdbc/auth/TokenCache.java | New implementation for encrypted token caching. |
| src/main/java/com/databricks/jdbc/auth/CachingExternalBrowserCredentialsProvider.java | New credentials provider implementation with token caching and refresh support. |
| src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java and src/main/java/com/databricks/jdbc/api/IDatabricksConnectionContext.java | Added a getter for the token cache passphrase. |
Files not reviewed (1)
- pom.xml: Language not supported
src/main/java/com/databricks/jdbc/auth/CachingExternalBrowserCredentialsProvider.java
Outdated
Show resolved
Hide resolved
# Conflicts: # src/main/java/com/databricks/jdbc/api/IDatabricksConnectionContext.java # src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java # src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java # src/main/java/com/databricks/jdbc/dbclient/impl/common/ClientConfigurator.java
…n-cache # Conflicts: # src/main/java/com/databricks/jdbc/api/IDatabricksConnectionContext.java # src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java # src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces support for token caching in the JDBC driver’s OAuth flow, enabling caching of tokens through the addition of two new URL parameters and corresponding tests. Key changes include:
- Adding new URL parameters (EnableTokenCache and TokenCachePassPhrase) in the connection context.
- Implementing a TokenCache class that encrypts and persists OAuth tokens.
- Extending authentication flows in the ClientConfigurator and CachingExternalBrowserCredentialsProvider to leverage cached tokens.
Reviewed Changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/com/databricks/jdbc/dbclient/impl/common/ClientConfiguratorTest.java | Updated tests to expect "external-browser-with-cache" auth type and a token passphrase setting |
| src/test/java/com/databricks/jdbc/auth/TokenCacheTest.java | Added tests for saving, loading, and validating token cache behavior |
| src/test/java/com/databricks/jdbc/auth/CachingExternalBrowserCredentialsProviderTest.java | Added tests confirming correct provider behavior with valid, expired, and missing tokens |
| src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java | Added tests to verify token cache enablement based on URL parameters |
| src/main/java/com/databricks/jdbc/dbclient/impl/common/ClientConfigurator.java | Updated to use the caching provider based on token cache enablement |
| src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java | Introduced TOKEN_CACHE_PASS_PHRASE and ENABLE_TOKEN_CACHE parameters |
| src/main/java/com/databricks/jdbc/auth/TokenCache.java | New implementation to encrypt and cache tokens locally |
| src/main/java/com/databricks/jdbc/auth/CachingExternalBrowserCredentialsProvider.java | New provider implementation which leverages cached tokens |
| src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java | Implemented accessors for token cache passphrase and enablement flag |
| src/main/java/com/databricks/jdbc/api/IDatabricksConnectionContext.java | Updated interface to include token cache methods |
Files not reviewed (1)
- pom.xml: Language not supported
Comments suppressed due to low confidence (2)
src/main/java/com/databricks/jdbc/auth/TokenCache.java:109
- Consider specifying an explicit cipher transformation (e.g., 'AES/CBC/PKCS5Padding') instead of relying on default behavior to ensure consistency across environments.
Cipher cipher = Cipher.getInstance(ALGORITHM);
src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java:110
- [nitpick] Consider renaming 'TokenCachePassPhrase' to 'TokenCachePassphrase' for consistency with common terminology and with the rest of the codebase.
TOKEN_CACHE_PASS_PHRASE("TokenCachePassPhrase", "Pass phrase to use for OAuth U2M Token Cache"),
| * @param context The connection context containing OAuth configuration parameters | ||
| * @param tokenCache The token cache to use for storing and retrieving tokens | ||
| */ | ||
| public CachingExternalBrowserCredentialsProvider( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are reusing lots of code from SDK. Can we do a better structure of class to reuse ExternalBrowserCredentialsProvider from SDK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ExternalBrowserCredentialsProvider does the hand-off to SessionCredentials internally. I was initially trying to overload those classes but it wouldn't just work
| * <p>This approach minimizes the need for users to repeatedly authenticate through the browser, | ||
| * improving the user experience while maintaining security through encryption of the cached tokens. | ||
| */ | ||
| public class CachingExternalBrowserCredentialsProvider extends RefreshableTokenSource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we check with SDK team if we should add this in SDK? Looks useful for other clients as well.
| try { | ||
| LOGGER.debug("Using refresh token to get new access token"); | ||
| Token refreshedToken = refreshAccessToken(); | ||
| tokenCache.save(refreshedToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, is this TokenCache the only diff with SDK implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Essentially, yes, + the logic on how/when to use token cache
| @VisibleForTesting | ||
| public TokenCache(Path cacheFile, String passphrase) { | ||
| if (passphrase == null || passphrase.isEmpty()) { | ||
| throw new IllegalArgumentException( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log this error
| byte[] encrypted = encrypt(json.getBytes()); | ||
| Files.write(cacheFile, encrypted); | ||
| } catch (Exception e) { | ||
| throw new IOException("Failed to save token cache: " + e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add logging
| byte[] decrypted = decrypt(encrypted); | ||
| return mapper.readValue(decrypted, SerializableToken.class); | ||
| } catch (Exception e) { | ||
| throw new IOException("Failed to load token cache: " + e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here also
| byte[] decrypted = decrypt(encrypted); | ||
| return mapper.readValue(decrypted, SerializableToken.class); | ||
| } catch (Exception e) { | ||
| throw new IOException("Failed to load token cache: " + e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens to IOException? Do we catch it any upstream class and handle it?
|
Closing in favour of #783 |
Description
Adds support for token cache to the JDBC driver, specifically adding two parameters: EnableTokenCache and TokenCachePassPhrase
Testing
Manual and unit tests
Additional Notes to the Reviewer