diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index 610b6cd0caa3..fa178c987e30 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Handles the scenario to gracefully handle unavalability of Key Ring on Linux platforms. [#46333](https://github.com/Azure/azure-sdk-for-java/pull/46333) + ### Other Changes ## 1.16.3 (2025-07-18) diff --git a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/PersistentTokenCacheImpl.java b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/PersistentTokenCacheImpl.java index 325f37fda50b..15972f814fa9 100644 --- a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/PersistentTokenCacheImpl.java +++ b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/PersistentTokenCacheImpl.java @@ -5,6 +5,7 @@ import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.implementation.util.IdentityUtil; import com.microsoft.aad.msal4j.ITokenCacheAccessAspect; import com.microsoft.aad.msal4j.ITokenCacheAccessContext; import com.microsoft.aad.msal4jextensions.PersistenceSettings; @@ -87,11 +88,15 @@ private PersistenceSettings getPersistenceSettings() { getCacheName(name != null ? name : DEFAULT_KEYRING_ITEM_NAME), DEFAULT_KEYRING_ATTR_NAME, DEFAULT_KEYRING_ATTR_VALUE, null, null); return persistenceSettingsBuilder.build(); - } catch (KeyRingAccessException e) { - if (!allowUnencryptedStorage) { - throw LOGGER.logExceptionAsError(e); + } catch (Exception e) { + if (e instanceof KeyRingAccessException || !IdentityUtil.isKeyRingAccessible()) { + if (!allowUnencryptedStorage) { + throw LOGGER.logExceptionAsError(e instanceof KeyRingAccessException + ? ((KeyRingAccessException) e) + : new RuntimeException(e)); + } + persistenceSettingsBuilder.setLinuxUseUnprotectedFileAsCacheStorage(true); } - persistenceSettingsBuilder.setLinuxUseUnprotectedFileAsCacheStorage(true); return persistenceSettingsBuilder.build(); } } diff --git a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/util/IdentityUtil.java b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/util/IdentityUtil.java index fdc22e2c016c..626017e08591 100644 --- a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/util/IdentityUtil.java +++ b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/util/IdentityUtil.java @@ -205,4 +205,31 @@ public static AuthenticationRecord loadVSCodeAuthRecord() throws IOException { // Deserialize to AuthenticationRecord return AuthenticationRecord.deserialize(json); } + + /** + * Checks if the GNOME Keyring is accessible. + * @return true if accessible, false otherwise. + */ + public static boolean isKeyRingAccessible() { + try { + ProcessBuilder processBuilder = new ProcessBuilder("secret-tool", "lookup", "test", "test"); + processBuilder.redirectErrorStream(true); + Process process = processBuilder.start(); + + int exitCode = process.waitFor(); + if (exitCode == 0) { + return true; // Keyring is accessible + } else { + LOGGER.verbose("GNOME Keyring is unavailable or inaccessible."); + return false; + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // Restore interrupted state if InterruptedException occurs + LOGGER.verbose("Error while checking GNOME Keyring availability: " + e.getMessage()); + return false; + } catch (IOException e) { + LOGGER.verbose("Error while checking GNOME Keyring availability: " + e.getMessage()); + return false; + } + } }