[wp-hackers] Querying OAuth protected service during 'wp_login'

Otto otto at ottodestruct.com
Tue Dec 4 18:04:24 UTC 2012


On Tue, Dec 4, 2012 at 10:20 AM, John Blackbourn
<johnbillion+wp at gmail.com> wrote:
> You could hook into the 'check_password' filter instead and do your
> oAuth request there if the username/password combo is correct. If your
> oAuth request fails you can them return false (and maybe also a
> wp_error object, you'll need to check) and the user won't get logged
> in. Then you should be able to hook into the 'login_errors' or
> 'login_messages' filters to display an appropriate message.

Try the 'authenticate' filter instead. It gets three parameters, the
WP_User object (or null), the username and the password (which may be
empty). It's expected to return a valid WP_User or a WP_Error, or the
original $user parameter if it's doing nothing.

So this, for example, will just log everybody in as user number 1:

add_filter('authenticate','dangerous_admin_login', 10, 3);
function dangerous_admin_login($user, $username, $password) {
  return new WP_User(1);
}

But, you can do more useful things with it, because this is how the
password check and cookie checks are hooked in.

The username/password check is hooked in at priority 20. It will
return a WP_Error when there's no username and password.

The cookie check is hooked in later, at priority 30. It validates the
authentication cookie, then replaces that WP_Error by returning a
valid WP_User when the cookie is valid.

If you hook in at, say, priority 40, then you can see that the user
has either successfully logged in (via username/password or via
cookie), and do what you want to do. If what you do should invalidate
their login, then you can just return your own WP_Error here,
overriding the previous two checks. The message from the WP_Error will
automatically get spit out onto the login screen. If they check out,
then you can just return the same WP_User you got in the first place,
and they'll be logged in.

Note that this authentication process happens every request, so you
may want to save something as usermeta so that you don't repeat your
OAuth stuff every time, and can just check that first and skip it if
they've successfully auth'd before.

Alternatively, if you want to tie your authentication into another
system entirely, you could hook in at priority 10, do your
authentication check, and *create* a new user in the WP database
corresponding to whatever your user-list is, or pull the proper
WP_User if the user already exists in WP. As long as you return a
WP_User object, the password check and the cookie check will simply
pass through and let the login happen. Note that the cookie-setting
code happens after this, so by returning a valid WP_User, then that
person will get the proper cookie and won't be needing to enter the
username and password all the time, since the cookie check will detect
them next time.

-Otto


More information about the wp-hackers mailing list