Investigating the filter authenticate
, we can find that it is called inside the function wp_authenticate
, which is a pluggable function.
That means that it can be replaced by one of our own making.
This is the original function, plus a marked entry point:
function wp_authenticate($username, $password) {
$username = sanitize_user($username);
$password = trim($password);
$user = apply_filters('authenticate', null, $username, $password);
/* ENTRY POINT */
if ( $user == null ) {
// TODO what should the error message be? (Or would these even happen?)
// Only needed if all authentication handlers fail to return anything.
$user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));
}
$ignore_codes = array('empty_username', 'empty_password');
if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) {
do_action('wp_login_failed', $username);
}
return $user;
}
The test was done creating a wp_authenticate
function inside a Must Use plugin. On that entry point, I put the following:
global $wpdb;
$table = $wpdb->prefix . 'my_users';
$parent = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM $table WHERE name="$username""
)
);
if( $username == $parent->name && $password == $parent->password )
$user = get_user_by( 'id', $parent->id );
The table wp_my_users
is a simple test table, password is even plain text.
The matter is how build the $user
object completely based on a custom table. Or if it is feasible or advisable…
Because in this test the ID of the users is the same, so we are giving back (get_user_by
) to WordPress a user from its own table wp_users
, but with credentials checked in a custom table wp_my_users
.
Notes:
This answer doesn’t goes beyond the analysis and hacking of the function wp_authenticate
. No consideration is done about security, password management nor the wp_usermeta
table.
For reference, this is the content of $user
:
user | WP_User Object
(
[data] => stdClass Object
(
[ID] => 1
[user_login] => rod
[user_pass] => $P$BQ8qnb3iYPRzisxYHUKq5X/GCQqhoz1
[user_nicename] => rod
[user_email] => [email protected]
[user_url] =>
[user_registered] => 2012-09-21 14:39:01
[user_activation_key] =>
[user_status] => 0
[display_name] => rod
)
[ID] => 1
[caps] => Array
(
[administrator] => 1
)
[cap_key] => wp_capabilities
[roles] => Array
(
[0] => administrator
)
[allcaps] => Array
(
[switch_themes] => 1
[edit_themes] => 1
[activate_plugins] => 1
[edit_plugins] => 1
[edit_users] => 1
[edit_files] => 1
[manage_options] => 1
[moderate_comments] => 1
[manage_categories] => 1
[manage_links] => 1
[upload_files] => 1
[import] => 1
[unfiltered_html] => 1
[edit_posts] => 1
[edit_others_posts] => 1
[edit_published_posts] => 1
[publish_posts] => 1
[edit_pages] => 1
[read] => 1
[level_10] => 1
[level_9] => 1
[level_8] => 1
[level_7] => 1
[level_6] => 1
[level_5] => 1
[level_4] => 1
[level_3] => 1
[level_2] => 1
[level_1] => 1
[level_0] => 1
[edit_others_pages] => 1
[edit_published_pages] => 1
[publish_pages] => 1
[delete_pages] => 1
[delete_others_pages] => 1
[delete_published_pages] => 1
[delete_posts] => 1
[delete_others_posts] => 1
[delete_published_posts] => 1
[delete_private_posts] => 1
[edit_private_posts] => 1
[read_private_posts] => 1
[delete_private_pages] => 1
[edit_private_pages] => 1
[read_private_pages] => 1
[delete_users] => 1
[create_users] => 1
[unfiltered_upload] => 1
[edit_dashboard] => 1
[update_plugins] => 1
[delete_plugins] => 1
[install_plugins] => 1
[update_themes] => 1
[install_themes] => 1
[update_core] => 1
[list_users] => 1
[remove_users] => 1
[add_users] => 1
[promote_users] => 1
[edit_theme_options] => 1
[delete_themes] => 1
[export] => 1
[administrator] => 1
)
[filter] =>
)