@solwininfotech,
Your plugin has been changed, yes. But not entirely for the better.
Your new code now has multiple new problems.
Putting a big
if (!is_wp_error($user) && is_object($user)) {
bracket around all your code and totally eliminating the get_user_by() (never actually translating the $username string) call might seem like a good idea, but not in reality.
All that bracket does is to protect YOURSELF from getting into the situation WordFence was in. That someone upstream passes YOU values that are not what you think. But it adds new issues.
Problem 1. The Authentication process starts by WordPress sending
(null, $username, $userpassword)
NULL.. As in, the first filter function will not have a WP_User at all as a parameter, but a ‘null’. The filter is responsible for filtering on $username/$userpassword and checking or looking up the username, when no $user structure has been found yet.
Or in the case, that the $username is for example a banned/illegal name, a filter might not try to look up the $username at all, but will simply return WP_User_Error.
A WP_User object is not found until the first filter translates the $username into a WP_User object. Then if the user and $userpassword is accepted by that particular filter, the filter passes a WP_User (rather than a WP_User_Error/WP_Error) as a return value.
Given that you are bracketing your entire function, that simply means that if you are first to be called from wp_authenticate(), you become a pass-though. Doing nothing at all. You never look up or otherwise check the $username.
This particular issue you are somewhat protected from, since WordPress initially inserts 3-4 internal ‘authenticate’ filters, which most likely would have translated $username before you ever get called. Why it might have appeared to work, when you tested it. But that is not an assumption that is really safe to make, since you are supposed to be able to handle NULL.
Problem 2. You are now returning NULL.
If there is a next filter in the chain AFTER you, like here WordFence, they might save the overall filter-result from your return value, because they are also responsible for accepting NULL as a first parameter. The next filter might then translate/validate/invalidate $username and return a correct value. But if you are alone or last in a filter-chain, you would be returning NULL to wp_authenticate() as the final filtering result..
NULL is not a valid return value from any ‘authenticate’ filter. No more valid than the earlier value of ‘false’.
wp_authenticate() in fact checks for NULL explicitly, and considers it a failure of the filter process that should not happen. It reacts by failing the whole login process, and declaring the login invalid.