Skip to content

Two sample implementations method for connecting to Azure PostgreSQL with Azure AD Passwordless authentication.

License

Notifications You must be signed in to change notification settings

spotakash/azure-postgresql-auth-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Azure PostgreSQL Passwordless Authentication with Java

Java Gradle Azure License: MIT PRs Welcome

Two complete implementations for connecting to Azure PostgreSQL with Azure AD Passwordless authentication.

🎯 Choose Your Approach

πŸ”Œ Azure Plugin Approach

Recommended for most use cases

compile 'com.azure:azure-identity-extensions:1.1.14'

βœ… Automatic token management
βœ… Built-in retry logic
βœ… Minimal code required
βœ… Production optimized

Location: azure-plugin-approach/

πŸ”§ Manual Token Approach

For custom scenarios and learning

compile 'com.azure:azure-identity:1.12.0'

βœ… Full control over authentication
βœ… Custom credential configuration
βœ… Detailed visibility
βœ… Flexible error handling

Location: manual-token-approach/

πŸš€ Quick Start

Test Individual Approaches

# Test Azure Plugin approach (recommended)
cd azure-plugin-approach && gradle run --quiet

# Test Manual Token approach
cd manual-token-approach && gradle run --quiet

Interactive Test Suite

# Linux/WSL/macOS
./test-auth.sh

# Windows
test-auth.bat

πŸ§ͺ Interactive Test Suite Features

The test scripts provide a comprehensive testing experience:

Menu Options:

  1. Test Azure Plugin Approach (Recommended)
  2. Test Manual Token Approach
  3. Test Both Approaches ← Compare side-by-side!
  4. Run Prerequisites Check Only
  5. Exit

Features:

  • βœ… 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

πŸ“ Project Structure

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

πŸ“Š Detailed Comparison

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

πŸ”‘ Authentication Methods Supported

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

πŸ”§ Implementation Details

Azure Plugin Approach

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

Manual Token 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

🌍 Environment Configuration

Local Development

az login  # Both approaches use Azure CLI automatically

Azure VM/App Service

# Enable managed identity on the resource
# Both approaches detect and use managed identity automatically

Azure Kubernetes (AKS)

# Configure workload identity
# Both approaches detect and use workload identity automatically

CI/CD Pipeline

# 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 automatically

πŸ” What the Tests Show

When you run the test suite, you'll see detailed output including:

Identity Detection

  • Available credential methods (1-7 in order)
  • Which method is actually being used
  • Environment variable status
  • Azure CLI authentication status

Connection Summary

  • 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

Example Output

πŸ“ 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

🎯 Decision Guide

Choose Azure Plugin Approach If:

  • βœ… Building production applications
  • βœ… Want minimal complexity
  • βœ… DefaultAzureCredential is sufficient
  • βœ… Standard authentication scenarios
  • βœ… Automatic token refresh is acceptable

Choose Manual Token Approach If:

  • βœ… Need custom credential logic
  • βœ… Require specific error handling
  • βœ… Want to understand authentication internals
  • βœ… Building educational/learning projects
  • βœ… Need non-standard credential configurations

🏁 Getting Started

  1. Prerequisites Check:

    # Ensure you have Java 17+, Gradle, and Azure CLI
    java -version
    gradle --version
    az --version
  2. Azure Authentication:

    az login
  3. ⚠️ 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";
  4. Test Everything:

    ./test-auth.sh    # Linux/WSL/macOS
    test-auth.bat     # Windows
  5. Choose and Implement:

    • Start with Azure Plugin Approach for most use cases
    • Switch to Manual Token Approach if you need custom logic

⚠️ Critical Notes

  1. Azure Plugin Dependency: The plugin is in azure-identity-extensions, NOT in the main azure-identity library.

  2. Gradle Version: This project uses Gradle 4.4.1 syntax (compile instead of implementation).

  3. Token Scope: Both approaches use the scope https://ossrdbms-aad.database.windows.net/.default for PostgreSQL.

  4. SSL Requirement: Both approaches enforce SSL with sslmode=require.

πŸŽ‰ Summary

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!

About

Two sample implementations method for connecting to Azure PostgreSQL with Azure AD Passwordless authentication.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published