diff --git a/changelog.html b/changelog.html
index f9713fda7c2a8395319b519d99684cf316a81008..06e69f3ff4c1d584de8c6816fca287015686d338 100644
--- a/changelog.html
+++ b/changelog.html
@@ -79,6 +79,9 @@ Upcoming changes
Show displayName in build remote API.
(issue 26723)
+
+ Added a switch (-Dhudson.model.User.allowNonExistentUserToLogin=true) to let users login even when the record is not found in the backend security realm.
+ (issue 22346)
diff --git a/core/src/main/java/hudson/model/User.java b/core/src/main/java/hudson/model/User.java
index d39b9b6f9d605d2ab5e17d394a6d13c3ccf33825..1ef3af9989b84f1fa58e33d6ce30c48fd4d3c3ae 100644
--- a/core/src/main/java/hudson/model/User.java
+++ b/core/src/main/java/hudson/model/User.java
@@ -304,7 +304,8 @@ public class User extends AbstractModelObject implements AccessControlled, Descr
// backend can't load information about other users. so use the stored information if available
} catch (UsernameNotFoundException e) {
// if the user no longer exists in the backend, we need to refuse impersonating this user
- throw e;
+ if (!ALLOW_NON_EXISTENT_USER_TO_LOGIN)
+ throw e;
} catch (DataAccessException e) {
// seems like it's in the same boat as UserMayOrMayNotExistException
}
@@ -976,5 +977,15 @@ public class User extends AbstractModelObject implements AccessControlled, Descr
}
}
+ /**
+ * Jenkins now refuses to let the user login if he/she doesn't exist in {@link SecurityRealm},
+ * which was necessary to make sure users removed from the backend will get removed from the frontend.
+ *
+ * Unfortunately this infringed some legitimate use cases of creating Jenkins-local users for
+ * automation purposes. This escape hatch switch can be enabled to resurrect that behaviour.
+ *
+ * JENKINS-22346.
+ */
+ public static boolean ALLOW_NON_EXISTENT_USER_TO_LOGIN = Boolean.getBoolean(User.class.getName()+".allowNonExistentUserToLogin");
}