Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a custom application with thousands of users who already have a password stored. I would like to set up a self hosted wordpress site to accompany that application and to use the usernames and encrypted passwords that already exist in that database.

Is there a way to configure Wordpress to not use the normal list of users, but instead to validate usernames and passwords against another database on another server?

We have a team of developers so if there was a way to write code to hook into the login process this would be acceptable. Does anyone have experience with this, or have any suggestions of where to look?

share|improve this question
    
Really what I am looking for is a way to replace the user list with a call to a different database, on that exists already from a different system. Any suggestions on where to start with this. –  Steve Stedman Nov 18 '12 at 2:39
    
Interesting thread at wp-hackers. –  brasofilo Dec 4 '12 at 21:00
add comment

4 Answers

up vote 3 down vote accepted
+50

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.
demo user table


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] => name@email.com
            [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] => 
)
share|improve this answer
    
great details. Thanks for the help. you get the bounty. –  Steve Stedman Nov 21 '12 at 4:11
    
@SteveStedman : Thanks, hope it can give a head start. Researching for the function and filter names in this Stack surely will provide handy info. Good luck! –  brasofilo Nov 21 '12 at 4:23
add comment

Actually you can bypass login mechanism of wordpress by login user automatically (after they succesfuly passed with credentials from another website for example) with this function: wp_set_auth_cookie($user_id);

for example with this you do login admin (user with id = 1)

wp_set_auth_cookie(1); //after this admin is logged in

so you can create user in wordpress with specified user privileges and then as user log with another credentials you can log him as this "placeholder" user.

share|improve this answer
add comment

Simplest method

add_filter( 'authenticate', 'my_auth', 10, 3 );

function my_auth( $user, $username, $password ){
    // your validation here.
    return $user;
}
share|improve this answer
add comment

I think this plugin External Database Authentication fits your needs. From there you might enable already logged-in users setting the cookie when they login just using wp_set_auth_cookie as @Roman says.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.