How to Secure MediaWiki with Two‑Factor Authentication and SSO Integration
Why strengthen MediaWiki login?
MediaWiki powers public wikis like Wikipedia and many private knowledge bases. Even a well‑configured password policy is not enough against credential stuffing, phishing or insider threats. Adding a second factor and centralising authentication through Single Sign‑On (SSO) raises the security bar dramatically while keeping the user experience smooth.
Core concepts
- Two‑Factor Authentication (2FA) – an extra secret, usually a time‑based one‑time password (TOTP), that must be supplied after the password.
- SSO – users authenticate once to an Identity Provider (IdP) and are then trusted by MediaWiki without re‑entering credentials.
- Extensions involved
OATHAuth– provides TOTP support.SamlSingleSignOnAuth– SAML‑based SSO.PluggableAuth– generic authentication framework used by many SSO extensions.OpenIDConnect– OIDC‑based SSO (useful for Azure AD, Keycloak, Google).
Step 1 – Install the extensions
All extensions are available from the MediaWiki extension directory. Use the git clone method or Composer where supported.
cd /path/to/mediawiki/extensions
# OATHAuth (2FA)
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/OATHAuth
# PluggableAuth – required for SAML/OIDC
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/PluggableAuth
# SamlSingleSignOnAuth – SAML SSO
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/SamlSingleSignOnAuth
# OpenIDConnect – OIDC SSO
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/OpenIDConnect
After cloning, add the extensions to LocalSettings.php:
wfLoadExtension( 'OATHAuth' );
wfLoadExtension( 'PluggableAuth' );
wfLoadExtension( 'SamlSingleSignOnAuth' );
wfLoadExtension( 'OpenIDConnect' );
Run the MediaWiki update script to create any needed database tables:
php maintenance/update.phpStep 2 – Enable and configure two‑factor authentication
Only users with the oathauth-enable right can enrol in 2FA. By default this right is granted to administrators, bureaucrats and other privileged groups. To make 2FA optional for all users, add the right to the user group:
$wgGroupPermissions['user']['oathauth-enable'] = true;Users will see an “Enable two‑factor authentication” link in their preferences (or can go directly to Special:OATH). The enrolment workflow:
- Scan the QR code with any TOTP app (Google Authenticator, FreeOTP, Aegis, etc.).
- Enter the six‑digit code generated by the app.
- Store the ten one‑time “scratch codes” in a safe place – they are the recovery mechanism if the device is lost.
For administrators who want to enforce 2FA for privileged accounts, add a hook that checks the user group on login and redirects to Special:OATH when the flag is missing.
$wgHooks['UserLoginComplete'][] = function ( $user, $inject_html, $direct ) {
if ( $user->isAllowed( 'twofactor' ) && !$user->getOption( 'oathauth-enabled' ) ) {
$user->setOption( 'oathauth-enabled', false );
$user->saveSettings();
// Force enrolment
header( "Location: {$wgScriptPath}/Special:OATH" );
exit;
}
return true;
};
Remember to grant the custom right twofactor to the groups you want to protect:
$wgGroupPermissions['sysop']['twofactor'] = true;
$wgGroupPermissions['bureaucrat']['twofactor'] = true;
Step 3 – Set up SAML‑based SSO (example with Azure AD)
SAML is a widely supported protocol for enterprise IdPs. The SamlSingleSignOnAuth extension uses PluggableAuth as its backend.
3.1 Create a SAML application in the IdP
In Azure AD create an “Enterprise Application”, choose “Non‑gallery application”, and configure the following:
- Identifier (Entity ID):
https://wiki.example.org/extensions/SamlSingleSignOnAuth/ - Reply URL (Assertion Consumer Service):
https://wiki.example.org/Special:SAMLLogin - Sign‑on URL (optional):
https://wiki.example.org/
Download the federation metadata XML – you will need it for MediaWiki.
3.2 MediaWiki configuration
Add the SAML settings to LocalSettings.php:
$wgMoSamlIdpName = 'AzureAD';
$wgMoSamlIssuer = 'https://sts.windows.net//'; // Entity ID from Azure
$wgMoSamlLoginURL = 'https://login.microsoftonline.com//saml2';
$wgMoSamlX509CertDesc = "-----BEGIN CERTIFICATE-----\n".
file_get_contents( '/path/to/azure‑metadata‑cert.pem' )."\n-----END CERTIFICATE-----";
$wgMoSamlIsResponseSigned = true;
$wgMoSamlIsAssertionSigned = true;
$wgMoSamlCreateUser = true; // auto‑create local accounts
$wgMoSamlUpdateUser = true; // sync attributes on each login
$wgMoSamlEmailAttr = 'mail';
$wgMoSamlUsernameAttr = 'uid';
$wgMoSamlRealNameAttr = 'displayName';
When a user clicks the “Log in via Azure AD” button (added automatically by the extension), they are redirected to Azure, authenticate, and are returned to Special:SAMLLogin. The extension extracts the attributes, creates or updates the local MediaWiki account and logs the user in.
Step 4 – OpenID Connect (OIDC) SSO (example with Keycloak)
OIDC is the modern, JSON‑based sibling of SAML. The OpenIDConnect extension also relies on PluggableAuth. Keycloak, Okta, Google Workspace and many others speak OIDC out of the box.
4.1 Register MediaWiki as a client in Keycloak
- Client ID:
mediawiki - Client protocol:
openid-connect - Valid redirect URIs:
https://wiki.example.org/Special:OpenIDConnect/callback - Enable “Standard Flow”.
- Copy the client secret – it will be used in the MediaWiki config.
4.2 MediaWiki configuration
$wgPluggableAuth_Config = [
[
'plugin' => 'OpenIDConnect',
'data' => [
'providerURL' => 'https://keycloak.example.org/auth/realms/wiki/.well-known/openid-configuration',
'clientID' => 'mediawiki',
'clientsecret' => 'YOUR_CLIENT_SECRET',
// map OIDC claims to MediaWiki fields
'email' => 'email',
'username' => 'preferred_username',
'realname' => 'name',
]
]
];
After saving, a “Log in with Keycloak” button appears on the login page. The flow mirrors the SAML case: the user authenticates at the IdP, the extension receives an ID token, validates the signature, extracts the claims, and either creates a new local account or updates an existing one.
Step 5 – Combine 2FA with SSO
SSO removes the need for a password inside MediaWiki, but it does not automatically add a second factor. Most IdPs already support MFA (Azure AD Conditional Access, Keycloak OTP, Okta MFA). The recommended approach is to let the IdP enforce the second factor, then rely on MediaWiki’s 2FA only for privileged local accounts that bypass SSO (e.g., service accounts).
If you still want a MediaWiki‑side TOTP after a successful SSO login (for defence‑in‑depth), enable OATHAuth for the user group that includes SSO‑authenticated users:
$wgGroupPermissions['sso-user']['oathauth-enable'] = true;
$wgGroupPermissions['sso-user']['twofactor'] = true; // custom right used in hook above
In the login hook, after a successful SSO session, redirect the user to Special:OATH if they have not yet enrolled.
Step 6 – Hardening the deployment
- HTTPS everywhere – enforce
$wgForceHTTPS = true;and configure HSTS. - Content Security Policy – limit where scripts can be loaded, especially important when using external SSO widgets.
- Limit login attempts – enable
LoginThrottleor a firewall rule to block brute‑force attacks. - Session security – set
$wgCookieSecure = true;and$wgCookieHttpOnly = true;. Shorten session lifetime with$wgSessionExpireSecondsif appropriate. - Audit logs – enable
Special:Log/oathto track 2FA enrolments and de‑enrolments, andSpecial:Log/authremoteuserfor SSO events.
Step 7 – Recovery procedures
If a user loses their TOTP device, they can use one of the scratch codes generated during enrolment. Administrators can reset 2FA with the maintenance script:
php extensions/OATHAuth/maintenance/disableOATHAuthForUser.php --user "JohnDoe"
For SSO‑only accounts, recovery is handled by the IdP – typically through a password‑reset flow or MFA re‑enrollment. Ensure the IdP’s self‑service portal is reachable and that the user’s email address is up‑to‑date.
Putting it all together
A typical production setup looks like this:
# Load core extensions
wfLoadExtension( 'OATHAuth' );
wfLoadExtension( 'PluggableAuth' );
wfLoadExtension( 'SamlSingleSignOnAuth' );
wfLoadExtension( 'OpenIDConnect' );
# Enforce HTTPS and secure cookies
$wgForceHTTPS = true;
$wgCookieSecure = true;
$wgCookieHttpOnly = true;
# Group permissions
$wgGroupPermissions['user']['oathauth-enable'] = true; // optional 2FA for all users
$wgGroupPermissions['sysop']['twofactor'] = true; // mandatory 2FA for admins
$wgGroupPermissions['sysop']['oathauth-enable'] = true;
$wgGroupPermissions['sso-user']['oathauth-enable'] = true;
$wgGroupPermissions['sso-user']['twofactor'] = true;
# SAML configuration (Azure AD example)
$wgMoSamlIdpName = 'AzureAD';
$wgMoSamlIssuer = 'https://sts.windows.net/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/';
$wgMoSamlLoginURL = 'https://login.microsoftonline.com/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/saml2';
$wgMoSamlX509CertDesc = "-----BEGIN CERTIFICATE-----\n".
file_get_contents( '/etc/mediawiki/azure‑cert.pem' )."\n-----END CERTIFICATE-----";
$wgMoSamlIsResponseSigned = true;
$wgMoSamlIsAssertionSigned = true;
$wgMoSamlCreateUser = true;
$wgMoSamlUpdateUser = true;
$wgMoSamlEmailAttr = 'mail';
$wgMoSamlUsernameAttr = 'uid';
$wgMoSamlRealNameAttr = 'displayName';
# OIDC configuration (Keycloak example)
$wgPluggableAuth_Config = [
[
'plugin' => 'OpenIDConnect',
'data' => [
'providerURL' => 'https://keycloak.example.org/auth/realms/wiki/.well-known/openid-configuration',
'clientID' => 'mediawiki',
'clientsecret' => 'SECRET',
'email' => 'email',
'username' => 'preferred_username',
'realname' => 'name',
]
]
];
# Hook to force 2FA enrolment for privileged groups
$wgHooks['UserLoginComplete'][] = function ( $user, $inject_html, $direct ) {
if ( $user->isAllowed( 'twofactor' ) && !$user->getOption( 'oathauth-enabled' ) ) {
header( "Location: {$GLOBALS['wgScriptPath']}/Special:OATH" );
exit;
}
return true;
};
With the configuration above, any user authenticating via Azure AD or Keycloak will be logged into MediaWiki automatically. Administrators, bureaucrats and any group granted the custom twofactor right will be forced to enrol in TOTP before they can continue using the wiki.
Conclusion
Combining OATHAuth for TOTP and a SAML or OpenID Connect SSO extension gives you layered protection:
- Credentials are never stored in MediaWiki – the IdP handles password policies and MFA.
- Local TOTP adds a safety net for high‑privilege accounts that might bypass the IdP.
- All authentication events are logged, making audit and incident response straightforward.
- The solution uses only official MediaWiki extensions, keeping the wiki up‑gradable and supported.
Deploy the steps incrementally, test each component in a staging environment, and you will have a hardened MediaWiki ready for the modern threat landscape.