A long time since I last did this on a site, but this is the gist.
You want to hook into wp_authenticate_user
which will fire after WP has tried to authenticate the user but before logging the user in.
You’ll receive either a WP_User
object or a WP_Error
object and you should return either a WP_User
object (if your own authentication check succeeds) or a WP_Error
object (if your auth fails). Something like this should work:
function wpse_232915_authenticate_user( $user ) {
/* already failed login attempt
return existing error or you'll subvert the login process:
*/
if ( is_wp_error( $user ) ) {
return $user;
}
$failure = your_own_authentication_tests( $user->ID ); // test if the user should be allowed in by your own rules
if ( $failure ) {
return new WP_Error( 'wpse_232915_user_expired', 'Sorry, you have expired!' );
}
return $user;
}
add_filter( 'wp_authenticate_user', 'wpse_232915_authenticate_user' );
Depending on how complex your test is, you could return the WP_Error object from that function rather than true/false as I’ve assumed here.
I’m not handy enough with WP_Error to know whether you can chain the errors, or whether the login error notification box would be happy with that, but that’s an improvement that might be worth looking into.