Use Access to make WP passwordless?

Longtime Cloudflare user, first time Access user here… bear with me.
Any tips and tricks appreciated.

We have multiple wordpress installs running on a single domain.
Is there any way to make the admin dashboard for all those wp installs loginless and directly accessible through CF access as separate applications?

I could figure out a way to make the admin dashboards public and put those applications behind Access but that doesn’t feel like the best course of action.
My understanding of SSO is very limited but that feels like the way to go about this.

Would love to hear if anyone has any tips how to get this running.

Thanks. Stay healthy.

You’d effectively need to have a (custom) plugin that looks for the headers Access passes:

But I’m not aware of an existing plugin that does this for you, sadly.

1 Like

Mhm I’ll look into that, thanks!
Been researching “Client Authentication Certificates”, from what I understand this could work as long as I manage to get that running on wordpress. It would keep the admin login page active, but add an option to login using a certificate.

@Judge is this what you had in mind? https://wordpress.org/plugins/jwt-auth/

You can try that, however, it might need to be modified to work with Access; I can’t say for certain.

Not sure if you ever got sorted on this.
JWT tokens and CA Certificates are defo the way to go.
As a fun project I knocked this together though I absolutely can’t vouch for it’s security (I can certainly vouch for it’s messy code-ness though, very rough draft).

NOT AT ALL GOOD FOR PRODUCTION, but thought it was worth sharing. It just uses the email header from Access to login if a user in WP matches that email. It also overrides the logout link to send the user to Access’s logout endpoint. There’s an error condition to die; if the Access user isn’t in Wordpress.

The problem is, because it’s sending users to Access for logout and not WP, the sessions don’t destroy correctly - meaning for a short period of time 2 people who both have Access permission and use the same machine can load each others profiles. Not good.

Anyway - will bump it up to github when it’s prettier (and I’ve worked out those kinks) - but here’s the dirty version for fun:

<?php
    /**
     * Plugin Name:       Cloudflare Access SSO
     * Plugin URI:        https://403page.com
     * Description:       Allow a single sign on to Wordpress when using Cloudflare Access.
     * Version:           0.1.0
     * Author:            403Page Labs
     * Author URI:        https://403page.com
     * License:           GPL-2.0+
     * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
     * Text Domain:       wp-access-sso
     * Domain Path:       /languages
     */

    // If this file is called directly, abort.
     if ( ! defined( 'WPINC' ) ) {
        die; }

    /**
     * Current plugin version.
     */
    define( 'WP_ACCESS_SSO_VERSION', '0.1.0' );

    // Go!
    add_action( 'plugins_loaded', 'nuke_existing_sessions' );

    function nuke_existing_sessions() {
    if ( ! is_user_logged_in() ) {
    	wp_destroy_current_session();
    	wp_clear_auth_cookie();
            wp_logout();
            wp_set_current_user( 0 );
    	}
    }

    add_action( 'after_setup_theme', 'new_login' );

    function new_login() {

        $emailauth = $_SERVER["HTTP_CF_ACCESS_AUTHENTICATED_USER_EMAIL"];
        $user = get_user_by( 'email', $emailauth );
        $user_id = $user->id;

        if ( $user_id > 0 && ! is_user_logged_in() ) {
            $user = get_user_by( 'id', $user_id );

            wp_clear_auth_cookie();
            wp_set_current_user( $user->ID, $user->user_login );
            wp_set_auth_cookie( $user->ID, true, is_ssl() );

            if ( is_user_logged_in() ) {
                return true;
            }

    	} elseif ( $user_id == 0 && is_user_logged_in() ) {
            wp_logout();
            wp_set_current_user( 0 );
    	} if ( $user_id == 0 ) {

            $nousermessage = 'User not found in site database. Please contact your site administrator for access.';

            echo '<html><body><center>';
            echo '<h1>Cloudflare Access mismatch:</h1>';
            echo $nousermessage;
            echo "<br /><a href='/cdn-cgi/access/logout'>Logout and try again...</a>";
            echo '</center></body></html>';
            die;
    	}
    }
    // Replace core logout URL with Cloudflare Access endpoint
    add_filter( 'logout_url', 'cf_access_logout_url' );
    function cf_access_logout_url( $default ) {
     $cfaccesslogouturl = '/cdn-cgi/access/logout';
     return is_user_logged_in() ? $cfaccesslogouturl : $default;
    }

Recently they announced Cloudflare Access for SaaS, this makes it possible for those applications who do not support JWT but supports SAML.

Basically, this is the plugin I use in WordPress to enable SAML integration:

1 Like

Here’s a revised version of what I posted above.
Should do the trick in a super simple way (make sure to follow the instructions to stay safe though):