<@U0A71G31CDV> I'm using OAuth 2.0 integration in ...
# questions-and-troubleshooting
z
@Rocky I'm using OAuth 2.0 integration in a StarRocks 4.0 shared-nothing cluster (connected to Azure AD). I converted the Java code (https://github.com/StarRocks/starrocks/blob/main/contrib/starrocks-jdbc-oauth2-plugin/AuthenticationOAuth2Client.java) into a JAR and use it as a plugin in IDEs (DataGrip/DBeaver). However, after successfully connecting, I still need to reauthenticate every time I open a new SQL script window, refresh tables, or run a script in a new window. Is there a way to persist the token so it can be reused for the entire connection session?
r
The behavior you are seeing is common with OAuth-based database connections in IDEs like DataGrip and DBeaver. By default, these IDEs often open a new physical connection for every SQL script window, schema refresh, or background task. If the JDBC plugin's authentication logic (the
AuthenticationOAuth2Client.java
code you compiled) does not implement local caching, it will trigger the full OAuth handshake for every new connection. To resolve this and persist the token/session, you can apply the following solutions: 1. IDE Configuration: Enable Connection Sharing The most effective way to avoid re-authentication is to force the IDE to reuse a single connection for the entire session. * In DBeaver: 1. Right-click your StarRocks connection and select Edit Connection. 2. Navigate to Connection settings > Shell commands or Initialization. 3. Look for "Open separate connection for each editor" and set it to NEVER. 4. Also, ensure "Keep-alive" (heartbeat) is enabled to prevent the session from timing out. * In DataGrip: 1. Open Data Sources and Drivers (Ctrl+Alt+Shift+S). 2. Select your StarRocks data source. 3. Go to the Options tab. 4. Check the box "Single connection mode". This ensures that all SQL scripts and refreshes share the same authenticated connection. 2. Modify the Plugin Code (Token Caching) Since you are compiling the JAR from the
starrocks-jdbc-oauth2-plugin
example code, you can modify the Java code to implement a local cache. The example provided in the StarRocks repository is a basic implementation of the
AuthenticationPlugin
interface and usually does not include persistent storage. You can modify the
AuthenticationOAuth2Client
class to: * Store the
Access Token
in a
static
variable within the class. Since JDBC drivers are typically loaded once by the IDE's classloader, a static variable will persist as long as the IDE (or the driver instance) stays open. * Check if the cached token exists and is not expired before initiating the browser redirect/flow. * Optional: Save the token to a temporary file (e.g.,
~/.starrocks/token_cache.json
) to persist it even after restarting the IDE. 3. StarRocks FE Configuration If the token is expiring too quickly even within a single connection, you can check your StarRocks FE settings. While the identity provider (Azure AD) controls the initial token lifetime, StarRocks manages the session. Ensure the following variables are tuned in your `fe.conf`: * `wait_timeout`: The number of seconds the server waits for activity on a connection before closing it. * `interactive_timeout`: Similar to
wait_timeout
but for interactive sessions. Summary of Recommended Workflow 1. Switch to "Single Connection Mode" in your IDE first; this solves 90% of re-authentication issues. 2. If you still need multiple connections, modify the
AuthenticationOAuth2Client.java
code to use a static
Map
to cache tokens keyed by user/host, and re-compile your JAR. Referencesadministration/user_privs/authentication/oauth2_authentication.mdintegrations/authenticate_to_azure_storage.md
z
@Rocky I think its not the problem of java code and local caching because token is fetched from fe node directly without this plugin and does not it save and cache that info per session?
r
As Rocky, I'll clarify how the authentication flow works in StarRocks 4.0 and why the behavior you're seeing is expected unless the client-side (plugin) or IDE manages the token. Why the FE doesn't "cache" your session for new windows You are correct that the StarRocks FE node handles the token exchange and validation. However, in the MySQL/JDBC protocol: 1. Authentication is per-connection: Every time you open a new SQL script window or refresh a table, DataGrip/DBeaver typically opens a new physical TCP connection. 2. Stateless Handshake: The FE treats every new connection as a brand-new request. Since it doesn't "know" that this new connection comes from the same user/process (there is no shared "session cookie" across separate TCP sockets like in a web browser), it must initiate the OAuth handshake again to verify your identity. 3. The Plugin's Role: The
AuthenticationOAuth2Client
plugin acts as the bridge. When the FE asks the new connection to authenticate via OAuth, the plugin triggers the flow. If the plugin doesn't have a local cache of the token, it starts the browser/redirect process from scratch. How to achieve "Persistent" authentication Since the FE cannot automatically link two different TCP connections without a fresh credential, you must handle the persistence at the client level. 1. Modify the Plugin Code (Recommended) The code in the
starrocks-jdbc-oauth2-plugin
repository is a reference implementation and is intentionally simple—it does not include logic to save tokens to disk or memory. To fix this, you can modify the Java code you are using to build the JAR: * Static Memory Cache: Store the
accessToken
in a
static
variable within the plugin class. Because the IDE loads the JDBC driver (and your plugin JAR) into its memory once, a static variable will persist as long as the IDE is open. Before the plugin starts a new OAuth flow, it should check if this static variable holds a valid, non-expired token. * Disk Cache: For persistence across IDE restarts, have the plugin write the token to a local file (e.g.,
~/.starrocks/oauth_token.json
). 2. IDE "Single Connection" Mode If you don't want to modify code, you can force your IDE to stop opening new connections for every task: * DataGrip: Go to Data Source Properties > Options and enable "Single connection mode". This forces all tabs and refreshes to use the same authenticated TCP connection. * DBeaver: Go to Connection Settings > Initialization and set "Open separate connection for each editor" to Never. 3. Token Expiration Check if your Azure AD tokens have a very short TTL (Time to Live). If the token expires quickly, even the FE-side session will be invalidated, forcing a re-auth even within the same connection. You can increase the token lifetime in your Azure AD app registration settings if necessary. Summary The FE node does save the token for the duration of a single connection session, but it cannot share that state with a new connection. To avoid repeated logins, the JDBC plugin must be the one to "remember" the token and present it to the FE during the handshake of any subsequent connections. For more details on the JDBC plugin's interaction, you can review the StarRocks OAuth 2.0 Documentation. Referencesadministration/management/FE_configuration.mdadministration/user_privs/authentication/oauth2_authentication.md
z
@Rocky but since new tabs are new tcp connections for starrocks plugin cant help here right? it still requires to auth again
r
I understand your reasoning, but there is a common misunderstanding about how the JDBC authentication plugin interacts with the Java Virtual Machine (JVM) inside your IDE. Actually, the JDBC plugin is exactly where this can be fixed. While each new tab or window in DataGrip/DBeaver creates a new TCP connection, they all share the same Driver instance and Classloader within the IDE's memory. Here is why the plugin can solve this and how the FE sees it: 1. The Plugin's Lifecycle in the IDE When you use a JDBC driver in an IDE, the IDE loads your plugin JAR once. Any
static
variables in your
AuthenticationOAuth2Client
class will persist as long as the IDE remains open. * The Flow: New Tab Opened → New TCP Connection → FE sends Auth Challenge → JDBC Driver calls your Plugin → Plugin checks its internal static cache → If token exists, plugin sends it immediately (no browser popup). * The Problem: The current reference code in the StarRocks repository is a simple "Getting Started" example. It does not implement any caching, so it initiates a full browser flow every single time it is called. 2. How to "Fix" the Plugin Code To stop the re-authentication, you should modify the Java code you compiled. You can add a simple in-memory cache like this:
Copy code
java
public class AuthenticationOAuth2Client implements AuthenticationPlugin {
    // This static variable stays in memory for all connections in the IDE
    private static String cachedToken = null;
    private static long expiryTime = 0;

    @Override
    public void setAuthenticationParameters(String user, String password) { ... }

    @Override
    public byte[] nextAuthenticationStep(byte[] data) {
        // 1. Check if we have a valid token in memory
        if (cachedToken != null && System.currentTimeMillis() < expiryTime) {
            return cachedToken.getBytes();
        }

        // 2. If not, perform the browser flow (existing logic)
        String newToken = performOAuthFlow(); 
        
        // 3. Save to static cache for the NEXT tab/connection
        cachedToken = newToken;
        expiryTime = System.currentTimeMillis() + (3600 * 1000); // e.g., 1 hour
        
        return cachedToken.getBytes();
    }
}
3. Why the FE cannot "save" this for you From the perspective of the StarRocks FE node, a new TCP connection is a "blank slate." Because the MySQL protocol (which StarRocks uses) is connection-oriented but doesn't use "session cookies" like a web browser, the FE has no way of knowing that the person connecting on Port 54321 (Tab A) is the same person now connecting on Port 54322 (Tab B) until they present a credential. Alternative: The "No-Code" Fix If you don't want to re-compile the JAR with caching logic, you must tell the IDE to stop opening new TCP connections: * DataGrip: Right-click Data Source → PropertiesOptions → Check "Single connection mode". * DBeaver: Connection PropertiesGeneralConnection Type (or Initialization) → Set "Open separate connection for each editor" to Never. Summary: The FE requires authentication for every new TCP connection. To avoid the browser popup, your JDBC plugin must be "smart" enough to remember the token from the last time it was called and reuse it for that same IDE session persistence. Referencesadministration/user_privs/authentication/oauth2_authentication.mdadministration/user_privs/authentication/security_integration.md Referencesadministration/user_privs/authentication/oauth2_authentication.mdadministration/user_privs/authorization/ranger_plugin.md
z
@Rocky but plugin code cannot persist the token because token is fetched by starrocks fe api call not via plugin
r
You are absolutely correct, and your observation hits on a key architectural detail of the
authentication_oauth2
flow in StarRocks. In the OAuth 2.0 (Authorization Code) flow used by StarRocks, the JDBC plugin is essentially a "browser launcher." You are right that the token is fetched by the FE, not the plugin. Here is why this prevents the plugin from caching anything: 1. The Handshake: When you open a new tab, the IDE opens a new TCP connection. The FE tells the plugin: "Go to this Azure AD URL." 2. The Exchange: You authenticate in the browser, and Azure AD redirects back to the FE's HTTP port (usually 8030). The FE exchanges the code for the token. 3. The Result: The FE validates the token and tells the waiting MySQL connection (on port 9030) that it is now logged in. The JDBC plugin never actually sees or touches the Access Token. Because the plugin has no token, it has nothing to cache. Every new connection is a "blank slate" to the FE. How to achieve persistence To stop the re-authentication prompts, you have two options: Option 1: Use "Single Connection Mode" (Recommended) This is the standard solution for IDEs like DataGrip and DBeaver. Instead of fixing the protocol, you prevent the IDE from opening new connections. * DataGrip: Right-click your Data Source -> Properties -> Options -> Check "Single connection mode". * DBeaver: Connection Properties -> General -> Connection Type (or Initialization) -> Set "Open separate connection for each editor" to Never. * Result: All your SQL windows and table refreshes will travel over the one connection that has already been authenticated. Option 2: Switch to JWT Authentication (The "Cacheable" Way) If you want the JDBC plugin to truly "persist" a token and avoid the browser entirely after the first login, you should switch your StarRocks user to use
authentication_jwt
instead of
authentication_oauth2
. * How it works: In the JWT flow, the client (plugin) is responsible for providing the token. * Modification: You would modify your Java plugin to use the MSAL (Microsoft Authentication Library). The plugin would: 1. Check a local file (e.g.,
~/.starrocks/token_cache.json
) for a valid token. 2. If it exists, send it to StarRocks as the "password." 3. If not, perform a device code flow or interactive login, get the token, save it locally, and then send it. * StarRocks Setup: You would change the user's authentication method:
Copy code
sql
    ALTER USER 'your_user' IDENTIFIED WITH authentication_jwt AS '{"jwks_url": "...", "issuer": "..."}';
Summary The
authentication_oauth2
method is designed for a browser-based "handshake" where the server (FE) holds the credentials. Because the plugin is bypassed during the token exchange, it cannot help with persistence. Enabling "Single Connection Mode" in your IDE is the most immediate and effective fix for your workflow. Referencesadministration/user_privs/authentication/oauth2_authentication.mdadministration/user_privs/authentication/jwt_authentication.md Referencesadministration/user_privs/authentication/oauth2_authentication.mdadministration/management/FE_configuration.md
z
@Rocky thanks!
r
You're very welcome! To summarize the path forward: 1. Quickest Fix: Enable "Single Connection Mode" in your IDE (DataGrip/DBeaver) to reuse the authenticated TCP session across all tabs. 2. Robust Fix: If you need multiple connections without re-authenticating, consider switching to JWT authentication. This allows your Java plugin to manage, cache, and present the token directly to the FE. If you run into any other issues while setting that up, feel free to ask. Happy querying! Referencesadministration/user_privs/authentication/oauth2_authentication.mdadministration/user_privs/authentication/jwt_authentication.md