diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java
index ac7862b..9630f3b 100755
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java
@@ -63,7 +63,25 @@ public class UpdateProfile implements RequiredActionProvider, RequiredActionFact
}
if (realm.isEditUsernameAllowed()) {
- user.setUsername(formData.getFirst("username"));
+ String username = formData.getFirst("username");
+ String oldUsername = user.getUsername();
+
+ boolean usernameChanged = oldUsername != null ? !oldUsername.equals(username) : username != null;
+
+ if (usernameChanged) {
+
+ if (session.users().getUserByUsername(username, realm) != null) {
+ Response challenge = context.form()
+ .setError(Messages.USERNAME_EXISTS)
+ .setFormData(formData)
+ .createResponse(UserModel.RequiredAction.UPDATE_PROFILE);
+ context.challenge(challenge);
+ return;
+ }
+
+ user.setUsername(username);
+ }
+
}
user.setFirstName(formData.getFirst("firstName"));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
index 531ee8a..545ce0c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
@@ -248,6 +248,29 @@ public class RequiredActionUpdateProfileTest {
}
@Test
+ public void updateProfileDuplicateUsername() {
+ loginPage.open();
+
+ loginPage.login("john-doh@localhost", "password");
+
+ updateProfilePage.assertCurrent();
+
+ updateProfilePage.update("New first", "New last", "new@email.com", "test-user@localhost");
+
+ updateProfilePage.assertCurrent();
+
+ // assert that form holds submitted values during validation error
+ Assert.assertEquals("New first", updateProfilePage.getFirstName());
+ Assert.assertEquals("New last", updateProfilePage.getLastName());
+ Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
+ Assert.assertEquals("", updateProfilePage.getUsername());
+
+ Assert.assertEquals("Username already exists.", updateProfilePage.getError());
+
+ events.assertEmpty();
+ }
+
+ @Test
public void updateProfileDuplicatedEmail() {
loginPage.open();