Two complete implementations for connecting to Azure PostgreSQL with Azure AD Passwordless authentication.
|
Recommended for most use cases compile 'com.azure:azure-identity-extensions:1.1.14'β
Automatic token management Location: |
For custom scenarios and learning compile 'com.azure:azure-identity:1.12.0'β
Full control over authentication Location: |
# Test Azure Plugin approach (recommended)
cd azure-plugin-approach && gradle run --quiet
# Test Manual Token approach
cd manual-token-approach && gradle run --quiet# Linux/WSL/macOS
./test-auth.sh
# Windows
test-auth.batThe test scripts provide a comprehensive testing experience:
- Test Azure Plugin Approach (Recommended)
- Test Manual Token Approach
- Test Both Approaches β Compare side-by-side!
- Run Prerequisites Check Only
- Exit
- β Prerequisites validation (Java, Gradle, Azure CLI)
- β Azure authentication check with auto-login prompt
- β Side-by-side comparison when testing both approaches
- β Detailed identity methods detection
- β Connection summaries with client IP and destination info
- β Interactive menu navigation
pg-test/
βββ azure-plugin-approach/ # Plugin-based implementation
β βββ src/main/java/com/example/PostgresTest.java
β βββ build.gradle # + azure-identity-extensions
β βββ settings.gradle
βββ manual-token-approach/ # Manual token implementation
β βββ src/main/java/com/example/PostgresTest.java
β βββ build.gradle # Standard azure-identity
β βββ settings.gradle
βββ test-auth.sh # Interactive test (Linux/WSL/macOS)
βββ test-auth.bat # Interactive test (Windows)
βββ README.md # This file
| Feature | Azure Plugin | Manual Token |
|---|---|---|
| Complexity | Simple | More Complex |
| Token Management | Automatic | Manual |
| Control Level | Standard | Full |
| Dependencies | azure-identity-extensions | azure-identity |
| Code Lines | ~30 lines | ~60 lines |
| Token Refresh | Automatic | Manual handling |
| Error Handling | Built-in retry | Custom implementation |
| Debugging | Limited visibility | Full visibility |
| Best For | Production apps | Custom scenarios |
Both approaches support all Azure environments automatically:
- π₯οΈ Local Development: Azure CLI (
az login) - βοΈ Azure VM/App Service: Managed Identity
- π’ Azure Kubernetes (AKS): Workload Identity
- π CI/CD Pipelines: Service Principal
Key Dependency:
dependencies {
compile 'org.postgresql:postgresql:42.7.3'
compile 'com.azure:azure-identity-extensions:1.1.14' // β THE KEY DEPENDENCY
compile 'com.azure:azure-identity:1.11.4'
}How it works:
// Plugin handles everything automatically
String jdbcUrl = "jdbc:postgresql://server:5432/db?sslmode=require" +
"&authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin";
Properties props = new Properties();
props.setProperty("user", "user@tenant.onmicrosoft.com");
// No password needed - plugin handles tokens automatically
Connection conn = DriverManager.getConnection(jdbcUrl, props);Benefits:
- β No manual token management required
- β Automatic token refresh handled by plugin
- β Built-in retry and error handling
- β Simpler code compared to manual approach
Dependencies:
dependencies {
compile 'org.postgresql:postgresql:42.7.3'
compile 'com.azure:azure-identity:1.12.0'
}How it works:
// Manual token acquisition and management
TokenCredential credential = new DefaultAzureCredentialBuilder().build();
TokenRequestContext context = new TokenRequestContext()
.addScopes("https://ossrdbms-aad.database.windows.net/.default");
AccessToken token = credential.getToken(context);
String jdbcUrl = "jdbc:postgresql://server:5432/db?sslmode=require";
Connection conn = DriverManager.getConnection(jdbcUrl, username, token.getToken());Benefits:
- β Full control over token acquisition and lifecycle
- β Custom credential configuration possible
- β Direct access to token metadata and expiration
- β Custom error handling and retry logic
az login # Both approaches use Azure CLI automatically# Enable managed identity on the resource
# Both approaches detect and use managed identity automatically# Configure workload identity
# Both approaches detect and use workload identity automatically# Set environment variables for service principal
export AZURE_CLIENT_ID="service-principal-id"
export AZURE_CLIENT_SECRET="service-principal-secret"
export AZURE_TENANT_ID="tenant-id"
# Both approaches use EnvironmentCredential automaticallyWhen you run the test suite, you'll see detailed output including:
- Available credential methods (1-7 in order)
- Which method is actually being used
- Environment variable status
- Azure CLI authentication status
- Client IP: Your outbound IP address
- Destination: Server FQDN and resolved IP
- Authentication Method: Azure AD Token-based Authentication
- Mechanism: Plugin vs Manual token management
- Account: Authenticated Azure AD account
- Protocol: PostgreSQL over SSL details
π Client IP: xx.xxx.xx.xxx
π Destination: server.postgres.database.azure.com:5432 (xx.x.x.x)
π Authentication: Azure AD Token-based Authentication
π§ Mechanism: AzurePostgresqlAuthenticationPlugin (DefaultAzureCredential)
π€ Account: admin@tenant.onmicrosoft.com
π Protocol: PostgreSQL over SSL (sslmode=require)
β‘ Token Management: Automatic refresh by plugin
- β Building production applications
- β Want minimal complexity
- β DefaultAzureCredential is sufficient
- β Standard authentication scenarios
- β Automatic token refresh is acceptable
- β Need custom credential logic
- β Require specific error handling
- β Want to understand authentication internals
- β Building educational/learning projects
- β Need non-standard credential configurations
-
Prerequisites Check:
# Ensure you have Java 17+, Gradle, and Azure CLI java -version gradle --version az --version -
Azure Authentication:
az login
-
β οΈ Configure Connection Details (REQUIRED):Before running tests, you MUST update the connection details in both approaches:
Edit Azure Plugin Approach:
# Edit: azure-plugin-approach/src/main/java/com/example/PostgresTest.java # Update these lines (around line 155): String host = "your-server.postgres.database.azure.com"; String database = "your-database-name"; String user = "your-user@yourdomain.onmicrosoft.com";
Edit Manual Token Approach:
# Edit: manual-token-approach/src/main/java/com/example/PostgresTest.java # Update these lines (around line 180): String host = "your-server.postgres.database.azure.com"; String database = "your-database-name"; String user = "your-user@yourdomain.onmicrosoft.com";
Example Configuration:
String host = "myserver.postgres.database.azure.com"; String database = "testdb"; String user = "admin@mycompany.onmicrosoft.com";
-
Test Everything:
./test-auth.sh # Linux/WSL/macOS test-auth.bat # Windows
-
Choose and Implement:
- Start with Azure Plugin Approach for most use cases
- Switch to Manual Token Approach if you need custom logic
-
Azure Plugin Dependency: The plugin is in
azure-identity-extensions, NOT in the mainazure-identitylibrary. -
Gradle Version: This project uses Gradle 4.4.1 syntax (
compileinstead ofimplementation). -
Token Scope: Both approaches use the scope
https://ossrdbms-aad.database.windows.net/.defaultfor PostgreSQL. -
SSL Requirement: Both approaches enforce SSL with
sslmode=require.
Both approaches achieve the same result - secure Azure AD authentication to PostgreSQL. The difference is in implementation complexity and control level:
- Azure Plugin Approach = Production-ready simplicity
- Manual Token Approach = Educational flexibility and full control
Choose based on your specific needs and complexity requirements!