WordPress

WordPress

WordPress Integration Guide

This comprehensive guide walks you through integrating WordPress with Keycloak for single sign-on (SSO) authentication. WordPress offers multiple plugin options for OAuth/OpenID Connect integration, each with different strengths and use cases.

Overview

WordPress Keycloak integration enables:

  • Single Sign-On (SSO) - Users authenticate once across all systems
  • Centralized User Management - Manage users in Keycloak, not WordPress
  • Role-Based Access Control - Map Keycloak roles to WordPress roles
  • Enhanced Security - Leverage Keycloak’s advanced security features
  • Unified User Experience - Seamless authentication across applications

Plugin Options

1. miniOrange OAuth Single Sign On (Recommended for Enterprise)

Best for: Enterprise environments requiring comprehensive features and professional support.

Key Features:

  • ✅ Native Keycloak support with pre-configured templates
  • ✅ Advanced role-based access control (RBAC)
  • ✅ 24/7 professional support
  • ✅ Unlimited users in free version
  • ✅ Multiple identity providers support

Installation:

# Via WordPress Admin
# 1. Go to Plugins > Add New
# 2. Search for "OAuth Single Sign On – SSO (OAuth Client)"
# 3. Install and activate

# Via WP-CLI
wp plugin install miniorange-login-with-eve-online-google-facebook --activate

2. OpenID Connect Generic Client (Recommended for Developers)

Best for: Developers who want a lightweight, free solution with full control.

Key Features:

  • ✅ Completely free with no premium limitations
  • ✅ Clean, minimalist implementation
  • ✅ Active open-source development
  • ✅ Developer-friendly with customization hooks
  • ✅ Reliable and battle-tested

Installation:

# Via WordPress Admin
# 1. Go to Plugins > Add New
# 2. Search for "OpenID Connect Generic Client"
# 3. Install and activate

# Via WP-CLI
wp plugin install openid-connect-generic --activate

3. WP OAuth Server (For Complex Architectures)

Best for: Complex multi-system architectures where WordPress needs to act as an identity provider.

Key Features:

  • ✅ WordPress as OAuth provider
  • ✅ Bidirectional authentication with Keycloak
  • ✅ Federation scenarios
  • ✅ Advanced integration patterns

Quick Start

Step 1: Create Keycloak Client

  1. Login to your Keycloak Admin Console
  2. Navigate to ClientsCreate Client
  3. Configure the client:
    • Client ID: wordpress-sso
    • Client Protocol: openid-connect
    • Client Authentication: Enable
    • Valid Redirect URIs: (depends on plugin choice)

Step 2: Configure WordPress Plugin

Choose your plugin and follow the specific configuration:

miniOrange Configuration:

  1. Go to SettingsminiOrange OAuthConfigure OAuth
  2. Select “Keycloak” from the application dropdown
  3. Enter your configuration:
    • Client ID: Your Keycloak client ID
    • Client Secret: From Keycloak credentials tab
    • Scope: openid email profile roles
  4. Configure endpoints (auto-populated for Keycloak)
  5. Set up attribute mapping:
    • Username: preferred_username
    • Email: email
    • First Name: given_name
    • Last Name: family_name
  6. Configure role mapping in the Role Mapping tab

Redirect URI for Keycloak:

https://your-site.com/wp-content/plugins/miniorange-login-with-eve-online-google-facebook/mo_oauth_callback.php

OpenID Connect Generic Configuration:

  1. Go to SettingsOpenID Connect Generic
  2. Enter your configuration:
    • Client ID: Your Keycloak client ID
    • Client Secret: From Keycloak credentials tab
    • OpenID Scope: openid email profile
  3. Configure endpoints:
    • Login Endpoint: https://your-keycloak/realms/your-realm/protocol/openid-connect/auth
    • Userinfo Endpoint: https://your-keycloak/realms/your-realm/protocol/openid-connect/userinfo
    • Token Endpoint: https://your-keycloak/realms/your-realm/protocol/openid-connect/token
    • End Session Endpoint: https://your-keycloak/realms/your-realm/protocol/openid-connect/logout

Redirect URIs for Keycloak:

https://your-site.com/wp-admin/admin-ajax.php?action=openid-connect-authorize
https://your-site.com/openid-connect-authorize

Production Configuration:

For production environments, use constants in wp-config.php:

// OpenID Connect Generic Plugin
define('OPENID_CONNECT_CLIENT_ID', 'your-client-id');
define('OPENID_CONNECT_CLIENT_SECRET', 'your-client-secret');
define('OPENID_CONNECT_SCOPE', 'openid email profile');
define('OPENID_CONNECT_LOGIN_ENDPOINT_URL', 'https://keycloak/realms/realm/protocol/openid-connect/auth');
define('OPENID_CONNECT_USERINFO_ENDPOINT_URL', 'https://keycloak/realms/realm/protocol/openid-connect/userinfo');
define('OPENID_CONNECT_TOKEN_VALIDATION_ENDPOINT_URL', 'https://keycloak/realms/realm/protocol/openid-connect/token');
define('OPENID_CONNECT_END_SESSION_ENDPOINT_URL', 'https://keycloak/realms/realm/protocol/openid-connect/logout');

// Security hardening
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);

Step 3: Test Integration

  1. Logout from WordPress completely
  2. Clear browser cache and cookies
  3. Navigate to your WordPress login page
  4. Click the SSO login button
  5. Authenticate in Keycloak
  6. Verify you’re redirected back and logged into WordPress

Role Mapping

Keycloak Configuration

Create role mappers in your Keycloak client:

  1. Go to ClientsYour ClientMappersCreate
  2. Configure the mapper:
    • Name: wordpress-roles
    • Mapper Type: User Realm Role
    • Token Claim Name: roles
    • Add to ID token: ON
    • Add to access token: ON

WordPress Role Mapping

miniOrange Plugin:

Role mapping is handled through the plugin’s UI:

  1. Go to SettingsminiOrange OAuthRole Mapping
  2. Map Keycloak roles to WordPress roles:
    • adminAdministrator
    • editorEditor
    • authorAuthor
    • userSubscriber

OpenID Connect Generic:

Add this code to your theme’s functions.php:

add_action('openid-connect-generic-update-user-using-current-claim', function($user, $user_claim) {
    if (!empty($user_claim['realm_access']['roles'])) {
        $roles = $user_claim['realm_access']['roles'];
        
        if (in_array('wordpress-admin', $roles)) {
            $user->set_role('administrator');
        } elseif (in_array('wordpress-editor', $roles)) {
            $user->set_role('editor');
        } elseif (in_array('wordpress-author', $roles)) {
            $user->set_role('author');
        } elseif (in_array('wordpress-contributor', $roles)) {
            $user->set_role('contributor');
        } else {
            $user->set_role('subscriber');
        }
    }
}, 10, 2);

Login Experience

Automatic Integration

Both plugins automatically add SSO login buttons to the WordPress login page. No additional configuration is needed.

Custom Login Buttons

Shortcode Integration:

Add SSO login to any page or post:

<!-- OpenID Connect Generic -->
[openid_connect_generic_login_button]

<!-- miniOrange (use plugin's shortcode generator) -->
[miniorange_sso_login]

PHP Integration:

Add to your theme templates:

<?php if (function_exists('openid_connect_generic_login_button')): ?>
    <div class="sso-login">
        <h3>Login with SSO</h3>
        <?php echo openid_connect_generic_login_button(); ?>
    </div>
<?php endif; ?>

Direct URL:

Create custom login links:

<a href="/wp-admin/admin-ajax.php?action=openid-connect-authorize" class="sso-login-btn">
    Login with Keycloak
</a>

Custom Styling

Style your SSO login buttons:

.openid-connect-login-button {
    background-color: #007cba;
    color: white;
    padding: 10px 20px;
    text-decoration: none;
    border-radius: 5px;
    display: inline-block;
    margin: 10px 0;
    font-weight: bold;
}

.openid-connect-login-button:hover {
    background-color: #005a87;
    color: white;
}

Security Best Practices

SSL/TLS Configuration

// Add to wp-config.php
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);

// Enable HSTS (in .htaccess or server config)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Secure Credential Storage

// Use environment variables
define('OPENID_CONNECT_CLIENT_SECRET', $_ENV['KEYCLOAK_CLIENT_SECRET']);

// Or use wp-config.php constants (not database)
define('OPENID_CONNECT_CLIENT_SECRET', 'your-secret-here');

Optional: Disable WordPress Login

// Force SSO-only authentication
add_filter('wp_authenticate_user', function($user) {
    if (!is_wp_error($user) && !current_user_can('manage_options')) {
        return new WP_Error('sso_only', 'Please use SSO to login');
    }
    return $user;
}, 10, 1);

Token Security

  • Use short access token lifetimes (15-30 minutes)
  • Implement refresh token rotation in Keycloak
  • Enable token validation and signature verification
  • Monitor for suspicious authentication patterns

Troubleshooting

Common Issues

“Invalid Client” Error:

  • ✅ Verify client ID and secret are correct
  • ✅ Check client authentication is enabled in Keycloak
  • ✅ Ensure no extra spaces in credentials
  • ✅ Verify client exists in the correct realm
  • ✅ Check client is not disabled

Debug Steps:

# Test client credentials
curl -X POST \
  https://your-keycloak/realms/your-realm/protocol/openid-connect/token \
  -d "grant_type=client_credentials" \
  -d "client_id=your-client-id" \
  -d "client_secret=your-client-secret"

Redirect URI Mismatch:

  • ✅ Copy exact callback URL from WordPress plugin settings
  • ✅ Add it to Keycloak’s Valid Redirect URIs
  • ✅ Check for HTTP vs HTTPS mismatches
  • ✅ Verify URL path is exactly correct
  • ✅ Include both callback and logout URLs

Common Callback URLs:

# miniOrange
https://your-site.com/wp-content/plugins/miniorange-login-with-eve-online-google-facebook/mo_oauth_callback.php

# OpenID Connect Generic
https://your-site.com/wp-admin/admin-ajax.php?action=openid-connect-authorize
https://your-site.com/openid-connect-authorize

SSL Certificate Issues:

  • ✅ Ensure complete certificate chain is installed
  • ✅ Check WordPress can reach Keycloak HTTPS endpoints
  • ✅ Verify system time synchronization
  • ✅ Test certificate validity

Debug Commands:

# Test SSL connection
openssl s_client -connect your-keycloak:443 -servername your-keycloak

# Check certificate
curl -I https://your-keycloak/auth/realms/your-realm/.well-known/openid-configuration

# Test from WordPress server
wp eval "echo file_get_contents('https://your-keycloak/auth/realms/your-realm/.well-known/openid-configuration');"

Missing User Attributes:

  • ✅ Verify required scopes are configured (openid, email, profile)
  • ✅ Check Keycloak user has all attributes populated
  • ✅ Review attribute mappings in both systems
  • ✅ Test with token introspection

Attribute Mapping:

Keycloak → WordPress
preferred_username → user_login
email → user_email
given_name → first_name
family_name → last_name
name → display_name

Debug Logging

Enable debug logging to troubleshoot issues:

// Add to wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

// For OpenID Connect Generic plugin
define('OPENID_CONNECT_GENERIC_LOG', true);

Check logs at /wp-content/debug.log for detailed error information.

Production Deployment

Pre-Deployment Checklist

Security Review:

  • ✅ All credentials stored securely (not in database)
  • ✅ SSL/TLS properly configured
  • ✅ Role mappings audited and tested
  • ✅ Redirect URIs restricted to necessary paths
  • ✅ Security headers enabled
  • ✅ WordPress and plugins updated
  • ✅ Monitoring and alerting configured
// Security hardening checklist
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
define('DISALLOW_FILE_EDIT', true);
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);

Performance Optimization:

  • ✅ Caching configured (Redis/Memcached)
  • ✅ Database queries optimized
  • ✅ CDN configured for static assets
  • ✅ Session storage optimized
  • ✅ Token lifetimes configured appropriately
// Performance settings
define('WP_CACHE', true);
define('WP_REDIS_HOST', 'localhost');
define('WP_REDIS_PORT', 6379);

// Session configuration
ini_set('session.gc_maxlifetime', 1800); // 30 minutes

Backup Strategy:

  • ✅ WordPress files and database backed up
  • ✅ Configuration files backed up
  • ✅ Keycloak realm configuration exported
  • ✅ Rollback procedures documented
  • ✅ Emergency access plan created
# Backup WordPress
wp db export backup.sql
tar -czf wp-backup.tar.gz wp-content/

# Backup Keycloak realm
./kcadm.sh get realms/your-realm > realm-backup.json

Testing Checklist:

  • ✅ SSO login works for all user types
  • ✅ Role mapping functions correctly
  • ✅ User attributes sync properly
  • ✅ Logout works (single logout)
  • ✅ Error handling works correctly
  • ✅ Performance under load tested
# Load testing
ab -n 1000 -c 10 https://your-site.com/wp-login.php

# Security testing
nmap -sS -sV your-site.com

Advanced Configuration

Multi-site WordPress

For WordPress multisite installations:

// Network-wide SSO configuration
define('OPENID_CONNECT_GENERIC_SETTINGS', serialize([
    'client_id' => 'your-client-id',
    'client_secret' => 'your-client-secret',
    'scope' => 'openid email profile',
    // ... other settings
]));

// Per-site role mapping
add_filter('openid_connect_generic_user_creation', function($user_data, $claims) {
    $site_id = get_current_blog_id();
    
    // Site-specific role mapping logic
    switch ($site_id) {
        case 1:
            $user_data['role'] = 'administrator';
            break;
        case 2:
            $user_data['role'] = 'editor';
            break;
        default:
            $user_data['role'] = 'subscriber';
    }
    
    return $user_data;
}, 10, 2);

WooCommerce Integration

For WooCommerce stores:

// Map Keycloak roles to WooCommerce roles
add_action('openid-connect-generic-update-user-using-current-claim', function($user, $user_claim) {
    if (!empty($user_claim['roles'])) {
        $roles = $user_claim['roles'];
        
        if (in_array('shop-manager', $roles)) {
            $user->set_role('shop_manager');
        } elseif (in_array('customer', $roles)) {
            $user->set_role('customer');
        }
    }
}, 10, 2);

// Sync customer data
add_action('openid-connect-generic-update-user-using-current-claim', function($user, $user_claim) {
    if (!empty($user_claim['billing_address'])) {
        update_user_meta($user->ID, 'billing_address_1', $user_claim['billing_address']['street']);
        update_user_meta($user->ID, 'billing_city', $user_claim['billing_address']['city']);
        // ... other billing fields
    }
}, 10, 2);

Support and Resources

Documentation

Professional Support

For enterprise deployments, consider:

  • WordPress VIP support
  • Keycloak Red Hat support
  • miniOrange enterprise support
  • Custom development services
  • Email Skycloak support at [email protected]

Conclusion

WordPress Keycloak integration provides a robust foundation for centralized authentication and user management. Choose the plugin that best fits your needs:

  • miniOrange for enterprise features and support
  • OpenID Connect Generic for developer flexibility and control
  • WP OAuth Server for complex federation scenarios

Follow the security best practices and testing procedures outlined in this guide to ensure a successful production deployment.