Details
diff --git a/events/api/src/main/java/org/keycloak/events/Errors.java b/events/api/src/main/java/org/keycloak/events/Errors.java
index fa5d49b..a0f536c 100755
--- a/events/api/src/main/java/org/keycloak/events/Errors.java
+++ b/events/api/src/main/java/org/keycloak/events/Errors.java
@@ -35,7 +35,9 @@ public interface Errors {
String NOT_ALLOWED = "not_allowed";
String IDENTITY_PROVIDER_NOT_FOUND = "identity_provider_not_found";
- String SOCIAL_ID_IN_USE = "social_id_in_use";
+ String FEDERATED_IDENTITY_EMAIL_EXISTS = "federated_identity_email_exists";
+ String FEDERATED_IDENTITY_USERNAME_EXISTS = "federated_identity_username_exists";
+ String FEDERATED_IDENTITY_DISABLED_REGISTRATION = "federated_identity_disabled_registration";
String SSL_REQUIRED = "ssl_required";
String USER_SESSION_NOT_FOUND = "user_session_not_found";
diff --git a/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties b/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
index bd8f0b2..577d9b5 100755
--- a/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
+++ b/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
@@ -55,6 +55,7 @@ emailExists=Email already exists
federatedIdentityEmailExists=User with email already exists. Please login to account management to link the account.
federatedIdentityUsernameExists=User with username already exists. Please login to account management to link the account.
+federatedIdentityDisabledRegistration=Registration of new users is not allowed. Please ask admin to register you and login to account management to link the account.
loginTitle=Log in to
loginOauthTitle=Temporary access.
diff --git a/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java b/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
index 01af03c..fd27d8c 100644
--- a/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
@@ -340,15 +340,28 @@ public class AuthenticationBrokerResource {
if (federatedUser == null) {
- UserModel existingUser = session.users().getUserByEmail(updatedIdentity.getEmail(), realm);
- String errorMessage = "federatedIdentityEmailExists";
+ String errorMessage = null;
- if (existingUser == null) {
+ // Check if no user already exists with this username or email
+ UserModel existingUser = session.users().getUserByEmail(updatedIdentity.getEmail(), realm);
+ if (existingUser != null) {
+ event.error(Errors.FEDERATED_IDENTITY_EMAIL_EXISTS);
+ errorMessage = "federatedIdentityEmailExists";
+ } else {
existingUser = session.users().getUserByUsername(updatedIdentity.getUsername(), realm);
- errorMessage = "federatedIdentityUsernameExists";
+ if (existingUser != null) {
+ event.error(Errors.FEDERATED_IDENTITY_USERNAME_EXISTS);
+ errorMessage = "federatedIdentityUsernameExists";
+ }
+ }
+
+ // Check if realm registration is allowed
+ if (!realm.isRegistrationAllowed()) {
+ event.error(Errors.FEDERATED_IDENTITY_DISABLED_REGISTRATION);
+ errorMessage = "federatedIdentityDisabledRegistration";
}
- if (existingUser == null) {
+ if (errorMessage == null) {
logger.debug("Creating user " + updatedIdentity.getUsername() + " and linking to federation provider " + providerId);
federatedUser = session.users().addUser(realm, updatedIdentity.getUsername());
federatedUser.setEnabled(true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
index 15eacda..1c912d3 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
@@ -232,11 +232,50 @@ public abstract class AbstractIdentityProviderTest {
accountFederatedIdentityPage.logout();
assertTrue(driver.getTitle().equals("Log in to realm-with-broker"));
- // Assert I am logged immediately to account management
+ // Assert I am logged immediately to account management due to previously linked "test-user" identity
loginPage.clickSocial(identityProviderModel.getId());
doAfterProviderAuthentication();
assertTrue(accountFederatedIdentityPage.isCurrent());
assertTrue(driver.getPageSource().contains("id=\"remove-" + identityProviderModel.getId() + "\""));
+
+ // Unlink my "test-user"
+ accountFederatedIdentityPage.clickRemoveProvider(identityProviderModel.getId());
+ assertTrue(driver.getPageSource().contains("id=\"add-" + identityProviderModel.getId() + "\""));
+
+ // Logout from account management
+ accountFederatedIdentityPage.logout();
+ assertTrue(driver.getTitle().equals("Log in to realm-with-broker"));
+
+ // Try to login. Previous link is not valid anymore, so now it should try to register new user
+ this.loginPage.clickSocial(identityProviderModel.getId());
+ doAfterProviderAuthentication();
+ this.updateProfilePage.assertCurrent();
+ }
+
+ @Test
+ public void testDisabledRegistration() {
+ // Disable registration in realm
+ getRealm().setRegistrationAllowed(false);
+ brokerServerRule.stopSession(this.session, true);
+ this.session = brokerServerRule.startSession();
+
+ // Login with identity provider
+ this.driver.navigate().to("http://localhost:8081/test-app/");
+ assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/realm-with-broker/protocol/openid-connect/login"));
+ this.loginPage.clickSocial(getProviderId());
+
+ assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8082/auth/"));
+ this.loginPage.login("test-user", "password");
+ doAfterProviderAuthentication();
+
+ WebElement element = this.driver.findElement(By.className("kc-feedback-text"));
+ assertNotNull(element);
+ assertEquals("Registration of new users is not allowed. Please ask admin to register you and login to account management to link the account.", element.getText());
+
+ // Re-enable registration in realm
+ getRealm().setRegistrationAllowed(true);
+ brokerServerRule.stopSession(this.session, true);
+ this.session = brokerServerRule.startSession();
}
@Test(expected = NoSuchElementException.class)
diff --git a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
index 8b372ae..182b131 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
@@ -4,6 +4,7 @@
"enabled": true,
"requiredCredentials": [ "password" ],
"resetPasswordAllowed": true,
+ "registrationAllowed": true,
"defaultRoles": [ "manager" ],
"privateKey": "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCCPyvTTb14vSMkpe/pds2P5Cqxk7bkeFnQiNMS1vyZ+HS2O79fxzp1eAguHnBTs4XTRT7SZJhIT/6utgqZjmDigKV5N7X5ptq8BM/W1qa1cYBRip261pc+tWf3IywJYQ9yFI9mUQarmIEl0D7GH16NSZklheaWfbodRVarvX+ML0amNtGYVDft/RftYmgbKKrK218qQp9R4GZFtf/Q/RmboNXN7weMINU8GWVkTRrccKBIXSunT6zXGfuj3Wp1YpVq20BWwY2OMM/P+yDAc7LKEO1LJqPBdT4r9BRn2lXiaga3AL24gTKZPKU/tu7uqfFciF+i4Rr58SMDNOzQcnklAgMBAAECggEAc0eibJYEO5d8QXW1kPgcHV2gBChv2mxDYnWYDLbIQSdNdfYP/qABt/MTmm5KkWr16fcCEYoD1w0mqFBrtVn1msSusUmEAYGTXJMNumOmjjX1kzaTQMmqeFBrwqwYz/xehWR5P+A7fSmwNV3KEeW19GvN5w5K96w0TLAQdFV3TQVPSytusDunwuR1yltMe1voaEDZ9z0Pi08YiEk2f6xhj5CMkoiw3mNImzfruphHullxU4FD05fH6tDeJ381527ILpAzDsgYZh4aFLKjUHem96bX4EL7FIzBJ6okgN78AZnUC/EaVfgFTw0qfhoWvZV4ruVXXiMhCg4CMMRDq/k9iQKBgQDBNWsJMT84OnnWmQoJmZogkFV+tsGrSK6Re+aJxLWpishh7dwAnT2OcagZvVdUb0FwNWu1D0B9/SKDDMRnnHBhOGDpH57m/eQdRU0oX1BD27xvffk0lLcfD4BTxnR5e9jss8K4twc9jf0P1rxC/loGJ2NtCH0BrPHgz54Ea+96ewKBgQCsk3JDaaPnFwzVYm2BXlhxOxLPsF4wvD2rIRAswZV4C5xebjand8nwiMmVpNd0PRLkEnkI+waURGv2EY/P3JsssoiY8Xqe8f/1G+SQKre7lbqOas8rFoALepC0BYDiZDFy0Z9ZnRAFzRI5sgIt7jpoMRD4xDNlmiV8X+yBxc3Y3wKBgQChDQsU1YUyNKQ8+sLAL9anEEkD4Ald4q8JPHN2IY+gLLxNzT0XEfsu0pTiJ8805axxgUYv3e/PVYNAJBNPnrqaf6lgiegl+jr9Hzhqz9CTUAYqFaL2boSakoxQyNtsLI0s+cb1vDN/3uy0GDZDzcty18BsMagqDmRtFgNNAj/UIwKBgQCahbeFBv0cOPZjxisY8Bou4N8aGehsqNBq/0LVYExuXa8YmoTTdJ3bgw9Er4G/ccQNdUDsuqAMeCtW/CiRzQ0ge4d1sprB4Rv3I4+HSsiS7SFKzfZLtWzXWlpg5qCdlWr1TR7qhYjIOPO9t1beO3YOvwhcRoliyyAPenBxTmTfbwKBgDtm2WJ5VlQgNpIdOs1CCiqd0DFmWOmvBPspPC1kySiy+Ndr9jNohRZkR7pEjgqA5E8rdzc88LirUN7bY5HFHRWN9KXrs5/o3O1K3GFCp64N6nvnPEYZ2zSJalcMC2fjSsJg26z8Dg1H+gfTIDUMoGiEAAnJXuqk+WayPU+fZMLn",
"publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgj8r0029eL0jJKXv6XbNj+QqsZO25HhZ0IjTEtb8mfh0tju/X8c6dXgILh5wU7OF00U+0mSYSE/+rrYKmY5g4oCleTe1+abavATP1tamtXGAUYqdutaXPrVn9yMsCWEPchSPZlEGq5iBJdA+xh9ejUmZJYXmln26HUVWq71/jC9GpjbRmFQ37f0X7WJoGyiqyttfKkKfUeBmRbX/0P0Zm6DVze8HjCDVPBllZE0a3HCgSF0rp0+s1xn7o91qdWKVattAVsGNjjDPz/sgwHOyyhDtSyajwXU+K/QUZ9pV4moGtwC9uIEymTylP7bu7qnxXIhfouEa+fEjAzTs0HJ5JQIDAQAB",