I’m about to start working on a prototype for a client – and one of the required features is integration with an in-house user authentication / registration system.
This system will act as the authoritative user database, and provides a RESTful interface for creating new users, and authenticating valid users.
-
I need to be able to create new users in WP and as part of that process make a call to the external authentication API to either create / validate that user.
-
A person who is a valid user but not known to WP should be able to login to comment, without needing to register on the WP site themselves.
-
A person logged into the overall website should also automatically be logged in to WordPress.
I’m thinking the following is the way to go.
For (1) – is there a registration hook I can use?
For (2) – I’m assuming i hook the authenticate filter – ie when someone tries to login, I trap that, make a call to the external system, and then either process the WP login or redirect them to the registration process where (1) takes oer.
For (3) – read the login cookie set by the main site and proceed with (2) ?
I guess I’ll also need to insert a record into the users and usermeta table.
So, does the above make sense – have I not thought about something. Anyone got any good resources for helping with this (@hakre – I saw you’ve done some work on this !!).
Update
So I’m still bashing my head against this a bit, essentially I’m trying to hook into the authenticate filter, and using that to:
- check if a login cookie for the ‘master’ site is set, and if it is, revalidate against their authentication API, and if valid, force a WP login with
wp_signon()
,using the information contained in the master site cookie (email and hashed password) as credentials for WP - if the cookie isn’t set, redirect to the master site login page and get either a login / signup then back to step 1
- if there isn’t a WP user when an authenticated master site user exists, create it and then so a ‘transparent’ signon (ie so the user doesn’t see a WP login form)
Basically, I want to hide the WP login form entirely for users who are just going to be mainly commenting, and later find a way to allow authors and admin to access it directly.
It’s going fairly slowly, here’s what I could use some help with:
-
is the authenticate filter the right one to use? It doesn’t seem to get called in all situations I would expect – eg the meta widget displays log in / log out links without the authenticate hook firing
-
i can get
wp_signon()
to return aWP_User
object (indicating success), but it doesn’t affect the logged in status – ie the meta widget would still be showin “Login” even after refreshing.
Any help gratefully received 🙂
OK, the approach that’s working for me is as follows:
Assume that the main site user database is authoritative. The main site login cookie contains an ID and a hash of the site password.
Get the cookie from the main site and revalidate it against the main site’s authentication API
If valid, use the email address from the return value as the
'user_login'
value for WP, and the hashed site password as the WP password.Test if this user exists in WP by using
wp_authenticate('user_login', 'user_pass')
. This returns aWP_User
object on success, or aWP_Error
object on failure.If
WP_Error/is_wp_error()
, then use usewp_update_user()
to create a user (or update a user with a changed password).Login via
wp_set_current_user()
,wp_set_auth_cookie()
anddo_action('wp_login, id)
(This is all contained in a function that’s attached to the
'init'
action)This seems to be working – valid site users unknown to WP are automatically created. Password changes are catered for, and if the site cookie is set, and the WP user exists, the SSO is automatic and pretty seamless.
The entire authentication system is pluggable. I suggest looking at existing plugins to get an idea how to override the system. Perhaps by looking at some LDAP plugins?
Several user-related function are defined conditionally on
!function_exists()
inwp-includes/pluggable.php
and are easy to override with your own versions.Enabling Single-Sign-On in WordPress took me 18+ hours of struggle but might take you only a few minutes:
Basically, you’ll want to use https://wordpress.org/plugins/wp-force-login/ and a modified version of https://as.wordpress.org/plugins/jwt-authenticator/ and then create an auth-protected endpoint on your main site that generates a JWT (JSON Web Token) and redirects back to the special URL of your WordPress site.
See full code here.