blogs

Add PHP authentication on WP-Login.php in WordPress

Posted 10 January 2019

Add PHP HTTP authentication for WP-Login.php for prevent Brute force attack on site and access WP admin

PHP HTTP authentication is use function header() to send an “Authentication Required” message to client to browser. It causing popup a username and password input window. Once the user has filled in a username and password. URL containing the PHP script will be called again with predefined variables PHP_AUTH_USER, PHP_AUTH_PW and PHP_AUTH_TYPE set to username, password and authentication type respectively

Before we code HTTP authentication just we add simple interface in WP admin settings to control authentication. It will contain three fields Enable authentication, username and password. So we are going to add in general setting page

Add Settings in general page

Going to add setting section, setting fields and register setting then hooks in to admin_init

add_action( "admin_init", "settings_wp_login_auth" );

/**

    add_settings_section (
       String for use in the id attribute of tags,
       Title of the section,
       Function that fills the section with the desired content. The function should echo its output,
       The type of settings page on which to show the section (general, reading, writing, media etc.),
    );

**/

/**

    add_settings_field (
      String for use in the 'id' attribute of tags,
      Title of the field,
      Function that fills the field with the desired inputs as part of the larger form. Name and id of the input should match the $id given to this function. The function should echo its output,
      The type of settings page on which to show the field (general, reading, writing, ...),
      The section of the settings page in which to show the box (default or a section you added with add_settings_section, look at the page in the source to see what the existing ones are.),
      Extra arguments passed into the callback function
    );

**/

function settings_wp_login_auth()
{
    add_settings_section(
        "settings_wp_login_auth", 
        "Login Credential for Wp-Login.php",
        "",
        "general"
    );

    add_settings_field(
        'settings_wp_login_auth_enable_fields',
        'Enable',
        'settings_auth_fields_enable_callback',
        'general',
        'settings_wp_login_auth'
    );

    add_settings_field(
        'settings_wp_login_auth_username_fields',
        'Auth Username',
        'settings_auth_username_fields_callback',
        'general',
        'settings_wp_login_auth'
    );

    add_settings_field(
        'settings_wp_login_auth_password_fields',
        'Auth Password',
        'settings_auth_password_fields_callback',
        'general',
        'settings_wp_login_auth'
    );


    register_setting( 'general', 'auth_enabled' );
    register_setting( 'general', 'auth_username' );
    register_setting( 'general', 'auth_password', "sanitize_auth_credential" );
}

Let’s add All callback functions for add_settings_fields

function settings_auth_fields_enable_callback()

{

    $credential = get_option( "auth_enabled" );

    ?>
    <p>

        <input <?php checked( "enabled", $credential, true ); ?>

            type="checkbox" name="auth_enabled" value="enabled">

        <label>Enable authentication for Wp-Login </label>

    </p>

    <?php

}



function settings_auth_username_fields_callback()

{

    $credential = get_option( "auth_username" );

    ?>

    <p>

        <input type="text" name="auth_username" class="regular-text"

               value="<?php echo isset( $credential ) ? $credential : ""; ?>">

    </p>

    <?php

}



function settings_auth_password_fields_callback()

{

    ?>
    <p><input type="password" name="auth_password" value="" class="regular-text"></p>

    <?php

}

 

Then we are going to add sanitize field for password field. Here we are going to hash our password and return to save. I used to hash password hash PHP function. Sanitize function name was added in the register_settings as a third argument (see above)

function sanitize_auth_credential( $password )

{
    if ( !empty( $password ) ) {

        return password_hash( $password, PASSWORD_DEFAULT );

    } else {

        return $password;

    }
}

See more about WorPress setting API

OK Now let’s implement Basic authentication. We are going to add authentication when WordPress init hooks fired

add_action( "init", "add_auth_wp_login_page" );

Now we have to check current page because we are adding only for WP-Login page only. So we use

$pagenow = $GLOBALS[ 'pagenow' ];

Above WordPress global variable return current page

Let’s create authenticate function. It sends authentication message to client browser

 
function authenticate()

{

    header( 'WWW-Authenticate: Basic realm="Test   Authentication System"' );

    header( 'HTTP/1.0 401 Unauthorized' );

    echo "Add Message when user click cancel button show message to user\n";

    exit;
 }

Now implement the add_auth_wp_login_page function to authenticate the username and password

function add_auth_wp_login_page()

{

    $pagenow = $GLOBALS[ 'pagenow' ];



    if ( $pagenow === "wp-login.php" ):



        $username = get_option( "auth_username" );

        $password = get_option( "auth_password" );

        $enabled = get_option( "auth_enabled", "disabled" );



        if ( !isset( $_SERVER[ 'PHP_AUTH_USER' ] ) && $enabled === "enabled" ) {

            authenticate();

        } else {

            if ( $_SERVER[ 'PHP_AUTH_USER' ] !== $username || !password_verify( $_SERVER[ 'PHP_AUTH_PW' ], $password ) ) {

                authenticate();

            }

        }

    endif;
}

See More about PHP HTTP authentication

Leave a Reply

Your email address will not be published. Required fields are marked *