2026年11月12日

2026年11月12日

WordPress SSO Setup: SAML, OpenID Connect and Google Login

This article is a localized edition of the Japanese original. Read the Japanese original

With SSO (single sign-on), employees and members can log in to WordPress with an account they already have (Google Workspace, Microsoft Entra ID, Okta and so on). There is no separate WordPress password to manage, and tasks such as disabling a departing employee's account can be done entirely on the identity provider (IdP) side.

In SSO, WordPress is the side that relies on someone else for login (the SP in SAML, the RP in OpenID Connect). The IdP handles authentication, and WordPress receives the result and logs the user in. This receiving part is usually implemented with a plugin.

SSO methods and how to choose

Method Main use How it works
Google login Log in with Google accounts or Google Workspace accounts OAuth 2.0 + OpenID Connect
OpenID Connect Integrate with IdPs that support OpenID Connect, such as Entra ID, Okta and Keycloak On top of OAuth 2.0, user information is passed in an ID token (JWT)
SAML 2.0 Integrate with corporate IdPs (Entra ID, Okta, Google Workspace, etc.) User information is passed in signed XML (SAML assertions)

As a rule of thumb:

  • If Google accounts are all you need, a Google login plugin is the easiest option
  • If your IdP also supports OpenID Connect, OpenID Connect is easier to handle because it has fewer settings
  • If company policy or the IdP requires SAML, use a SAML 2.0 plugin

Plugins for each method

All of these plugins are distributed on wordpress.org (as of October 2026).

Method Plugin Characteristics
Google login Log in with Google Google login only. Can also be configured with constants in wp-config.php
OpenID Connect OpenID Connect Generic Client Generic OpenID Connect client. Supports adding a button to the login screen and automatic login
SAML 2.0 WP SAML Auth Bundles the OneLogin SAML library. Configured in the admin or with a filter
SAML 2.0 SAML Single Sign On – SSO Login SAML plugin by miniOrange, configured in the admin. Features differ between the free and paid versions

Note that "WP OAuth Server" (slug oauth2-provider) turns WordPress into an IdP (an OAuth 2.0 authorization server) so that other apps can log in with WordPress accounts. That is the opposite direction from SSO where an external IdP logs users in to WordPress, so choose according to your goal.

Logging in with Google accounts

Create an OAuth client in Google Cloud, register https://example.com/wp-login.php as an authorized redirect URI, and enter the client ID and secret in Log in with Google. If only your Google Workspace organization will use it, set the consent screen audience to "Internal" on the Google side, and restrict registration to your company domain in the plugin. The following article explains the steps in detail.

Integrating with OpenID Connect

With OpenID Connect Generic Client, you register an app (client) with the IdP, then enter the issued client ID and secret plus the URLs of the IdP's authorization, token and userinfo endpoints on the plugin's settings screen.

By default, the redirect URI to register with the IdP looks like this.

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

If the IdP does not accept redirect URIs with a query string, check "Alternate Redirect URI" on the settings screen to use https://example.com/openid-connect-authorize instead. See the following article for concrete settings.

Integrating with SAML (WP SAML Auth and Microsoft Entra ID)

This example uses WP SAML Auth to integrate with Microsoft Entra ID (formerly Azure AD) over SAML. WP SAML Auth lets you set the main options under Settings → WP SAML Auth, but only filter-based configuration covers every option. Once you configure it with a filter, the admin settings page is disabled.

Step 1: Install the plugin

wp plugin install wp-saml-auth --activate

Step 2: Register the app in Entra ID

Do the following in the Microsoft Entra admin center (screen names as of October 2026).

  1. Under Entra ID → Enterprise apps, select "New application", then "Create your own application" to create a non-gallery app
  2. In the new app's "Single sign-on", choose "SAML"
  3. In "Basic SAML Configuration", enter the two values in the table below
  4. Download "Certificate (Base64)" from "SAML Certificates", and note the tenant ID and login URL shown in the "Set up" section
  5. Under "Users and groups", assign the users or groups that may log in to WordPress
Entra ID field Value
Identifier (Entity ID) urn:example.com (the SP entity ID of WordPress; must match the value built by the code in Step 4)
Reply URL (Assertion Consumer Service URL) https://example.com/wp-login.php

WP SAML Auth receives the IdP's response at wp-login.php. If WordPress is installed in a subdirectory, use the actual login page URL.

Step 3: Add the tenant ID and certificate path to wp-config.php

Put the downloaded certificate file outside the public directory (document root).

<?php
// Add to wp-config.php above the "That's all, stop editing!" line
define( 'SAML_TENANT_ID', '00000000-0000-0000-0000-000000000000' );   // Entra ID tenant ID
define( 'SAML_IDP_CERT_FILE', '/home/example/saml/entra-id.cer' );    // Keep outside the public directory

SAML_TENANT_ID and SAML_IDP_CERT_FILE are names chosen for the code in this article.

Step 4: Write the WP SAML Auth configuration as an mu-plugin

The configuration filter must load before the plugin initializes. To keep it independent of the theme, save it as wp-content/mu-plugins/wp-saml-auth-config.php.

<?php
/**
 * Plugin Name: WP SAML Auth settings (Microsoft Entra ID)
 * Description: Place in wp-content/mu-plugins/. This file takes precedence and the admin settings page is disabled.
 */

add_filter( 'wp_saml_auth_option', function ( $value, $option_name ) {
    // Defined in wp-config.php: SAML_TENANT_ID (tenant ID), SAML_IDP_CERT_FILE (certificate file path)
    if ( ! defined( 'SAML_TENANT_ID' ) || ! defined( 'SAML_IDP_CERT_FILE' ) ) {
        return $value;
    }

    $idp_url = 'https://login.microsoftonline.com/' . SAML_TENANT_ID . '/saml2';
    $claims  = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/';

    $options = [
        'connection_type'        => 'internal',
        'internal_config'        => [
            'strict'  => true,
            'debug'   => defined( 'WP_DEBUG' ) && WP_DEBUG,
            'baseurl' => home_url(),
            'sp'      => [
                'entityId'                 => 'urn:' . wp_parse_url( home_url(), PHP_URL_HOST ),
                'assertionConsumerService' => [
                    'url'     => wp_login_url(),
                    'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
                ],
            ],
            'idp'     => [
                'entityId'            => 'https://sts.windows.net/' . SAML_TENANT_ID . '/',
                'singleSignOnService' => [
                    'url'     => $idp_url,
                    'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
                ],
                'singleLogoutService' => [
                    'url'     => $idp_url,
                    'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
                ],
                'x509cert'            => file_get_contents( SAML_IDP_CERT_FILE ),
            ],
        ],
        'auto_provision'         => true,          // Create users that do not exist yet
        'permit_wp_login'        => true,          // Keep username/password login too
        'get_user_by'            => 'email',       // Match existing users by email address
        'user_login_attribute'   => $claims . 'name',
        'user_email_attribute'   => $claims . 'emailaddress',
        'display_name_attribute' => $claims . 'name',
        'first_name_attribute'   => $claims . 'givenname',
        'last_name_attribute'    => $claims . 'surname',
        'default_role'           => 'subscriber',  // Role for auto-created users
    ];

    return array_key_exists( $option_name, $options ) ? $options[ $option_name ] : $value;
}, 10, 2 );

The main settings mean the following.

Setting Meaning
connection_type internal uses the OneLogin SAML library bundled with the plugin
strict in internal_config Validates SAML responses strictly. Keep it true
auto_provision Whether to create users who do not exist in WordPress. With false, only users created in advance can log in
permit_wp_login Whether to keep username/password login. Keep it true until testing is done
get_user_by Matches existing users by email (email address) or login (username)
user_*_attribute Which SAML response attribute maps to which WordPress field
default_role Role for auto-created users

Attribute names such as http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress are the claim names Entra ID sends by default. If you change the claims in Entra ID's "Attributes & Claims", or use another IdP, match the attribute names the IdP actually sends. If they do not match, login fails with the error ""…" attribute is expected, but missing".

Step 5: Test it

  1. Open https://example.com/wp-login.php in a private browser window and check that a SAML login button is shown
  2. Click it, sign in on the Entra ID page with an assigned user, and check that you return to WordPress logged in
  3. In the Users list, check that auto-created users have the role set in default_role

Once everything checks out, set permit_wp_login to false if you want to disable non-SAML login. Even then, keep SSH or FTP access to the server so you can revert the setting in an emergency.

Do not write your own SAML handler

You may come across code that handles SAML itself, for example on the init hook, reading $_POST['SAMLResponse'] and logging the user in. But unless a SAML response is properly checked for its signature, recipient (Audience and Destination), validity period and replay, anyone can impersonate any user with a forged response. Leave this to a maintained library or plugin. WP SAML Auth itself has shipped updates fixing issues in its bundled library and user matching, so keep the plugin up to date.

Cautions

  • Keep a local emergency administrator: so you can still get in if SSO stops working because of an IdP outage or an expired certificate, keep one administrator account that does not depend on SSO, with a strong password and two-factor authentication
  • Give auto-created users minimal rights: set default_role to a minimal role such as subscriber, and grant editor or administrator rights individually in WordPress
  • Certificate renewal: the IdP's signing certificate expires. When the IdP renews it, replace the certificate file on the WordPress side too
  • Server clock: SAML assertions have a validity period, so validation fails if the server clock is far off. Keep the time in sync with NTP or similar
  • Where to keep secrets: do not put OpenID Connect client secrets or certificate files in theme files or the public directory. Use constants in wp-config.php and locations outside the document root

Summary

  • In SSO, WordPress is the SP (RP) and leaves authentication to the IdP. A plugin handles the receiving side
  • Use Log in with Google for Google only, OpenID Connect Generic Client for IdPs that support OpenID Connect, and WP SAML Auth or similar when SAML is required
  • WP SAML Auth can be fully configured with the wp_saml_auth_option filter; register wp-login.php as the ACS on the IdP
  • Keep password login until testing is done, and build a local emergency administrator, minimal rights for auto-created users and certificate renewal into your operations

Related articles

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲