While talking to one of the users troubleshooting their problem, I discovered that an AD forest can be set up such that the top-level domain does allow anonymous binds, but sub-domains do not.
In such a situation, the anonymous bind will succeed, but when Jenkins tries to locate any users in it, it'll not find them, as users are all defined in sub-domains.
As a result, any attempt to ActiveDirectoryUnixAuthenticationProvider.retrieveUser(name,null) (i.e., loading user without having his password) will fail with UsernameNotFoundException and not UserMayOrMayNotExistException.
This makes Jenkins believe that it has positively determined that the user no longer exists in AD, and thus refuses to let the user login with API token, even if the API token matches up.
Jenkins' behaviour is reasonable here, as this is the only situation where Jenkins can positively determine that the user do not exist. If we treat this situation as UserMayOrMayNotExistException, there will never be UsernameNotFoundException, and we'll end up allowing users to login via API token even after he was removed from AD — a security hole.
I'm not sure how to address this, but leaving this as an open issue to see if other people are impacted by this, and see if we can come up with some compromise to avoid this kind of hard-to-diagnose problems.
|