keycloak-uncached
Changes
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java 19(+0 -19)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java 2(+1 -1)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java 28(+0 -28)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java 2(+1 -1)
services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java 35(+0 -35)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java 221(+97 -124)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java 6(+1 -5)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java 26(+0 -26)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/OIDCKeyCloakServerBrokerBasicTest.java 14(+12 -2)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java 23(+16 -7)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java 8(+6 -2)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/util/UserSessionStatusServlet.java 8(+6 -2)
Details
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
index 745e16d..72c39f1 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
@@ -129,8 +129,9 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
@Override
public Response keycloakInitiatedBrowserLogout(UserSessionModel userSession, UriInfo uriInfo, RealmModel realm) {
if (getConfig().getLogoutUrl() == null || getConfig().getLogoutUrl().trim().equals("")) return null;
+ String sessionId = userSession.getId();
UriBuilder logoutUri = UriBuilder.fromUri(getConfig().getLogoutUrl())
- .queryParam("state", userSession.getId());
+ .queryParam("state", sessionId);
String idToken = userSession.getNote(FEDERATED_ID_TOKEN);
if (idToken != null) logoutUri.queryParam("id_token_hint", idToken);
String redirect = RealmsResource.brokerUrl(uriInfo)
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
index e2a1902..b3efc97 100755
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
@@ -7,6 +7,8 @@ import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.broker.provider.IdentityProvider;
import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.dom.saml.v2.assertion.AttributeType;
import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
import org.keycloak.dom.saml.v2.assertion.NameIDType;
@@ -36,6 +38,7 @@ import org.keycloak.saml.common.util.StaxParserUtil;
import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
+import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
import org.keycloak.saml.processing.core.util.XMLSignatureUtil;
@@ -295,6 +298,19 @@ public class SAMLEndpoint {
break;
}
}
+ if (assertion.getAttributeStatements() != null ) {
+ for (AttributeStatementType attrStatement : assertion.getAttributeStatements()) {
+ for (AttributeStatementType.ASTChoiceType choice : attrStatement.getAttributes()) {
+ AttributeType attribute = choice.getAttribute();
+ if (X500SAMLProfileConstants.EMAIL.getFriendlyName().equals(attribute.getFriendlyName())
+ || X500SAMLProfileConstants.EMAIL.get().equals(attribute.getName())) {
+ if (!attribute.getAttributeValue().isEmpty()) identity.setEmail(attribute.getAttributeValue().get(0).toString());
+ }
+ }
+
+ }
+
+ }
String brokerUserId = config.getAlias() + "." + subjectNameID.getValue();
identity.setBrokerUserId(brokerUserId);
identity.setIdpConfig(config);
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java b/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java
old mode 100644
new mode 100755
index 784ba8e..7ba3bb7
--- a/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java
@@ -1,9 +1,10 @@
package org.keycloak.migration;
-import java.util.List;
import org.keycloak.provider.Provider;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import java.util.List;
+
/**
* Various common utils needed for migration from older version to newer
*
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index 026e35e..2382f55 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -116,10 +116,6 @@ public interface ClientModel extends RoleContainerModel {
void setNotBefore(int notBefore);
- void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders);
- List<ClientIdentityProviderMappingModel> getIdentityProviders();
- boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId);
-
Set<ProtocolMapperModel> getProtocolMappers();
ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model);
void removeProtocolMapper(ProtocolMapperModel mapping);
diff --git a/model/api/src/main/java/org/keycloak/models/Constants.java b/model/api/src/main/java/org/keycloak/models/Constants.java
index edba3e3..08cf4ee 100755
--- a/model/api/src/main/java/org/keycloak/models/Constants.java
+++ b/model/api/src/main/java/org/keycloak/models/Constants.java
@@ -8,6 +8,7 @@ public interface Constants {
String ADMIN_CONSOLE_CLIENT_ID = "security-admin-console";
String ACCOUNT_MANAGEMENT_CLIENT_ID = "account";
+ String BROKER_SERVICE_CLIENT_ID = "broker";
String INSTALLED_APP_URN = "urn:ietf:wg:oauth:2.0:oob";
String INSTALLED_APP_URL = "http://localhost";
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ProtocolMapperEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ProtocolMapperEntity.java
index 21330e5..29ffca2 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/ProtocolMapperEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/ProtocolMapperEntity.java
@@ -1,7 +1,5 @@
package org.keycloak.models.entities;
-import org.keycloak.models.ProtocolMapperModel;
-
import java.util.Map;
/**
diff --git a/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java b/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java
index ed2282c..26ff18e 100755
--- a/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java
+++ b/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java
@@ -1,5 +1,7 @@
package org.keycloak.models;
+import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -8,8 +10,6 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
-
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 9f66440..63be7f0 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -1,7 +1,6 @@
package org.keycloak.models.utils;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderMapperModel;
@@ -14,8 +13,6 @@ import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
-import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
@@ -261,10 +258,6 @@ public class ModelToRepresentation {
rep.setRegisteredNodes(new HashMap<>(clientModel.getRegisteredNodes()));
}
- if (!clientModel.getIdentityProviders().isEmpty()) {
- rep.setIdentityProviders(toRepresentation(clientModel.getIdentityProviders()));
- }
-
if (!clientModel.getProtocolMappers().isEmpty()) {
List<ProtocolMapperRepresentation> mappings = new LinkedList<>();
for (ProtocolMapperModel model : clientModel.getProtocolMappers()) {
@@ -276,21 +269,6 @@ public class ModelToRepresentation {
return rep;
}
- private static List<ClientIdentityProviderMappingRepresentation> toRepresentation(List<ClientIdentityProviderMappingModel> identityProviders) {
- ArrayList<ClientIdentityProviderMappingRepresentation> representations = new ArrayList<ClientIdentityProviderMappingRepresentation>();
-
- for (ClientIdentityProviderMappingModel model : identityProviders) {
- ClientIdentityProviderMappingRepresentation representation = new ClientIdentityProviderMappingRepresentation();
-
- representation.setId(model.getIdentityProvider());
- representation.setRetrieveToken(model.isRetrieveToken());
-
- representations.add(representation);
- }
-
- return representations;
- }
-
public static UserFederationProviderRepresentation toRepresentation(UserFederationProviderModel model) {
UserFederationProviderRepresentation rep = new UserFederationProviderRepresentation();
rep.setId(model.getId());
diff --git a/model/api/src/main/java/org/keycloak/models/utils/reflection/MethodPropertyImpl.java b/model/api/src/main/java/org/keycloak/models/utils/reflection/MethodPropertyImpl.java
old mode 100644
new mode 100755
index 6fa8786..7e2952e
--- a/model/api/src/main/java/org/keycloak/models/utils/reflection/MethodPropertyImpl.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/reflection/MethodPropertyImpl.java
@@ -1,13 +1,13 @@
package org.keycloak.models.utils.reflection;
+import org.keycloak.util.reflections.Reflections;
+
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
-import org.keycloak.util.reflections.Reflections;
-
/**
* A bean property based on the value represented by a getter/setter method pair
*/
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index 0312ff4..282d376 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -6,7 +6,6 @@ import org.keycloak.enums.SslRequired;
import org.keycloak.migration.MigrationProvider;
import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.models.ClaimMask;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderMapperModel;
@@ -23,7 +22,6 @@ import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
-import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
@@ -41,7 +39,6 @@ import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.util.UriUtils;
import java.io.IOException;
-import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -612,8 +609,6 @@ public class RepresentationToModel {
}
}
- client.updateIdentityProviders(toModel(resourceRep.getIdentityProviders(), realm));
-
return client;
}
@@ -662,7 +657,6 @@ public class RepresentationToModel {
}
}
- updateClientIdentityProviders(rep.getIdentityProviders(), resource);
}
public static long getClaimsMask(ClaimRepresentation rep) {
@@ -918,37 +912,4 @@ public class RepresentationToModel {
return model;
}
- private static List<ClientIdentityProviderMappingModel> toModel(List<ClientIdentityProviderMappingRepresentation> repIdentityProviders, RealmModel realm) {
- List<ClientIdentityProviderMappingModel> result = new ArrayList<ClientIdentityProviderMappingModel>();
-
- if (repIdentityProviders != null) {
- for (ClientIdentityProviderMappingRepresentation rep : repIdentityProviders) {
- ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
-
- identityProviderMapping.setIdentityProvider(rep.getId());
- identityProviderMapping.setRetrieveToken(rep.isRetrieveToken());
-
- result.add(identityProviderMapping);
- }
- }
-
- return result;
- }
-
- private static void updateClientIdentityProviders(List<ClientIdentityProviderMappingRepresentation> identityProviders, ClientModel resource) {
- if (identityProviders != null) {
- List<ClientIdentityProviderMappingModel> result = new ArrayList<ClientIdentityProviderMappingModel>();
-
- for (ClientIdentityProviderMappingRepresentation mappingRepresentation : identityProviders) {
- ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
-
- identityProviderMapping.setIdentityProvider(mappingRepresentation.getId());
- identityProviderMapping.setRetrieveToken(mappingRepresentation.isRetrieveToken());
-
- result.add(identityProviderMapping);
- }
-
- resource.updateIdentityProviders(result);
- }
- }
}
diff --git a/model/api/src/main/java/org/keycloak/provider/ConfiguredProvider.java b/model/api/src/main/java/org/keycloak/provider/ConfiguredProvider.java
index d37afcd..c737306 100755
--- a/model/api/src/main/java/org/keycloak/provider/ConfiguredProvider.java
+++ b/model/api/src/main/java/org/keycloak/provider/ConfiguredProvider.java
@@ -1,7 +1,5 @@
package org.keycloak.provider;
-import org.keycloak.provider.ProviderConfigProperty;
-
import java.util.List;
/**
diff --git a/model/api/src/main/java/org/keycloak/provider/ProviderEventManager.java b/model/api/src/main/java/org/keycloak/provider/ProviderEventManager.java
index efdfa82..dfe6782 100755
--- a/model/api/src/main/java/org/keycloak/provider/ProviderEventManager.java
+++ b/model/api/src/main/java/org/keycloak/provider/ProviderEventManager.java
@@ -1,8 +1,5 @@
package org.keycloak.provider;
-import org.keycloak.provider.ProviderEvent;
-import org.keycloak.provider.ProviderEventListener;
-
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
diff --git a/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java b/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java
old mode 100644
new mode 100755
index 14f28fb..d091dca
--- a/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java
+++ b/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java
@@ -1,11 +1,11 @@
package org.keycloak.models;
-import static org.junit.Assert.fail;
+import org.junit.Assert;
+import org.junit.Test;
import java.util.regex.PatternSyntaxException;
-import org.junit.Assert;
-import org.junit.Test;
+import static org.junit.Assert.fail;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
index 34ddb06..7068a26 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
@@ -16,12 +16,18 @@
*/
package org.keycloak.models.file.adapter;
+import org.keycloak.connections.file.InMemoryModel;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.entities.ClientEntity;
+import org.keycloak.models.entities.ProtocolMapperEntity;
+import org.keycloak.models.entities.RoleEntity;
+import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -30,14 +36,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.keycloak.connections.file.InMemoryModel;
-import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.entities.ClientEntity;
-import org.keycloak.models.entities.ClientIdentityProviderMappingEntity;
-import org.keycloak.models.entities.ProtocolMapperEntity;
-import org.keycloak.models.entities.RoleEntity;
-import org.keycloak.models.utils.KeycloakModelUtils;
/**
* ApplicationModel used for JSON persistence.
@@ -364,48 +362,6 @@ public class ClientAdapter implements ClientModel {
}
@Override
- public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
- List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();
-
- for (ClientIdentityProviderMappingModel model : identityProviders) {
- ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity();
-
- entity.setId(model.getIdentityProvider());
- entity.setRetrieveToken(model.isRetrieveToken());
- stored.add(entity);
- }
-
- entity.setIdentityProviders(stored);
- }
-
- @Override
- public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
- List<ClientIdentityProviderMappingModel> models = new ArrayList<>();
-
- for (ClientIdentityProviderMappingEntity e : entity.getIdentityProviders()) {
- ClientIdentityProviderMappingModel model = new ClientIdentityProviderMappingModel();
-
- model.setIdentityProvider(e.getId());
- model.setRetrieveToken(e.isRetrieveToken());
-
- models.add(model);
- }
-
- return models;
- }
-
- @Override
- public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
- for (ClientIdentityProviderMappingEntity identityProviderMappingModel : entity.getIdentityProviders()) {
- if (identityProviderMappingModel.getId().equals(providerId)) {
- return identityProviderMappingModel.isRetrieveToken();
- }
- }
-
- return false;
- }
-
- @Override
public String getClientId() {
return entity.getClientId();
}
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java
index f53c0ce..9448def 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java
@@ -16,18 +16,18 @@
*/
package org.keycloak.models.file.adapter;
-import java.util.ArrayList;
-import java.util.Collections;
+import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
+import org.keycloak.models.entities.RoleEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.entities.RoleEntity;
/**
* RoleModel for JSON persistence.
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
index 0937e2c..6e622cc 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
@@ -16,10 +16,12 @@
*/
package org.keycloak.models.file.adapter;
+import org.keycloak.connections.file.InMemoryModel;
import org.keycloak.models.ClientModel;
import static org.keycloak.models.utils.Pbkdf2PasswordEncoder.getSalt;
+import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
@@ -28,7 +30,11 @@ import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.entities.CredentialEntity;
+import org.keycloak.models.entities.FederatedIdentityEntity;
+import org.keycloak.models.entities.RoleEntity;
+import org.keycloak.models.entities.UserEntity;
import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
+import org.keycloak.util.Time;
import java.util.ArrayList;
import java.util.Collections;
@@ -39,12 +45,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.keycloak.connections.file.InMemoryModel;
-import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.entities.FederatedIdentityEntity;
-import org.keycloak.models.entities.RoleEntity;
-import org.keycloak.models.entities.UserEntity;
-import org.keycloak.util.Time;
+import static org.keycloak.models.utils.Pbkdf2PasswordEncoder.getSalt;
/**
* UserModel for JSON persistence.
diff --git a/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java b/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
old mode 100644
new mode 100755
index 5c50a59..8dd783d
--- a/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
+++ b/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
@@ -16,34 +16,33 @@
*/
package org.keycloak.models.file;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-
-import org.keycloak.models.ProtocolMapperModel;
-import org.keycloak.models.file.adapter.UserAdapter;
+import org.keycloak.connections.file.FileConnectionProvider;
+import org.keycloak.connections.file.InMemoryModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.CredentialValidationOutput;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
+import org.keycloak.models.entities.FederatedIdentityEntity;
+import org.keycloak.models.entities.UserEntity;
+import org.keycloak.models.file.adapter.UserAdapter;
+import org.keycloak.models.utils.CredentialValidation;
import org.keycloak.models.utils.KeycloakModelUtils;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
-import org.keycloak.connections.file.FileConnectionProvider;
-import org.keycloak.connections.file.InMemoryModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.CredentialValidationOutput;
-import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.entities.FederatedIdentityEntity;
-import org.keycloak.models.entities.UserEntity;
-import org.keycloak.models.utils.CredentialValidation;
/**
* UserProvider for JSON persistence.
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
index 436405e..4dc4a03 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
@@ -1,7 +1,6 @@
package org.keycloak.models.cache;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
@@ -250,24 +249,6 @@ public class ClientAdapter implements ClientModel {
}
@Override
- public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
- getDelegateForUpdate();
- updated.updateIdentityProviders(identityProviders);
- }
-
- @Override
- public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
- if (updated != null) return updated.getIdentityProviders();
- return cached.getIdentityProviders();
- }
-
- @Override
- public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
- if (updated != null) return updated.isAllowedRetrieveTokenFromIdentityProvider(providerId);
- return cached.isAllowedRetrieveTokenFromIdentityProvider(providerId);
- }
-
- @Override
public Set<ProtocolMapperModel> getProtocolMappers() {
if (updated != null) return updated.getProtocolMappers();
return cached.getProtocolMappers();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
index 16c77d1..a37e2a4 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
@@ -2,12 +2,12 @@ package org.keycloak.models.cache;
import org.keycloak.models.ClientModel;
import org.keycloak.models.CredentialValidationOutput;
+import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
-import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
index c586927..58d3cb0 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
@@ -1,14 +1,12 @@
package org.keycloak.models.cache.entities;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.RealmCache;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -37,7 +35,6 @@ public class CachedClient {
private int notBefore;
private Set<String> scope = new HashSet<String>();
private Set<String> webOrigins = new HashSet<String>();
- private List<ClientIdentityProviderMappingModel> identityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
private Set<ProtocolMapperModel> protocolMappers = new HashSet<ProtocolMapperModel>();
private boolean surrogateAuthRequired;
private String managementUrl;
@@ -67,7 +64,6 @@ public class CachedClient {
for (RoleModel role : model.getScopeMappings()) {
scope.add(role.getId());
}
- this.identityProviders = model.getIdentityProviders();
for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
this.protocolMappers.add(mapper);
}
@@ -145,34 +141,10 @@ public class CachedClient {
return frontchannelLogout;
}
- public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
- return this.identityProviders;
- }
-
- public boolean hasIdentityProvider(String providerId) {
- for (ClientIdentityProviderMappingModel model : getIdentityProviders()) {
- if (model.getIdentityProvider().equals(providerId)) {
- return true;
- }
- }
-
- return false;
- }
-
public Set<ProtocolMapperModel> getProtocolMappers() {
return protocolMappers;
}
- public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
- for (ClientIdentityProviderMappingModel model : getIdentityProviders()) {
- if (model.getIdentityProvider().equals(providerId)) {
- return model.isRetrieveToken();
- }
- }
-
- return false;
- }
-
public boolean isSurrogateAuthRequired() {
return surrogateAuthRequired;
}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
index b0b7069..5cf96ec 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
@@ -2,11 +2,11 @@ package org.keycloak.models.cache;
import org.keycloak.models.ClientModel;
import org.keycloak.models.CredentialValidationOutput;
+import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
-import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index f9f62b6..b290e48 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -1,15 +1,12 @@
package org.keycloak.models.jpa;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ClientEntity;
-import org.keycloak.models.jpa.entities.ClientIdentityProviderMappingEntity;
-import org.keycloak.models.jpa.entities.IdentityProviderEntity;
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.jpa.entities.ScopeMappingEntity;
@@ -263,88 +260,6 @@ public class ClientAdapter implements ClientModel {
return copy;
}
- @Override
- public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
- Collection<ClientIdentityProviderMappingEntity> entities = entity.getIdentityProviders();
- Set<String> already = new HashSet<>();
- List<ClientIdentityProviderMappingEntity> remove = new ArrayList<>();
-
- for (ClientIdentityProviderMappingEntity entity : entities) {
- IdentityProviderEntity identityProvider = entity.getIdentityProvider();
- boolean toRemove = true;
-
- for (ClientIdentityProviderMappingModel model : identityProviders) {
- if (model.getIdentityProvider().equals(identityProvider.getAlias())) {
- toRemove = false;
- break;
- }
- }
-
- if (toRemove) {
- remove.add(entity);
- } else {
- already.add(entity.getIdentityProvider().getAlias());
- }
- }
- for (ClientIdentityProviderMappingEntity entity : remove) {
- entities.remove(entity);
- em.remove(entity);
- }
- em.flush();
- for (ClientIdentityProviderMappingModel model : identityProviders) {
- ClientIdentityProviderMappingEntity mappingEntity = null;
-
- if (!already.contains(model.getIdentityProvider())) {
- mappingEntity = new ClientIdentityProviderMappingEntity();
- entities.add(mappingEntity);
- } else {
- for (ClientIdentityProviderMappingEntity entity : entities) {
- if (entity.getIdentityProvider().getAlias().equals(model.getIdentityProvider())) {
- mappingEntity = entity;
- break;
- }
- }
- }
-
- TypedQuery<IdentityProviderEntity> query = em.createNamedQuery("findIdentityProviderByAlias", IdentityProviderEntity.class).setParameter("alias", model.getIdentityProvider());
- IdentityProviderEntity identityProviderEntity = query.getSingleResult();
-
- mappingEntity.setIdentityProvider(identityProviderEntity);
- mappingEntity.setClient(this.entity);
- mappingEntity.setRetrieveToken(model.isRetrieveToken());
-
- em.persist(mappingEntity);
- }
- em.flush();
- }
-
- @Override
- public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
- List<ClientIdentityProviderMappingModel> models = new ArrayList<ClientIdentityProviderMappingModel>();
-
- for (ClientIdentityProviderMappingEntity entity : this.entity.getIdentityProviders()) {
- ClientIdentityProviderMappingModel model = new ClientIdentityProviderMappingModel();
-
- model.setIdentityProvider(entity.getIdentityProvider().getAlias());
- model.setRetrieveToken(entity.isRetrieveToken());
-
- models.add(model);
- }
-
- return models;
- }
-
- @Override
- public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
- for (ClientIdentityProviderMappingModel model : getIdentityProviders()) {
- if (model.getIdentityProvider().equals(providerId)) {
- return model.isRetrieveToken();
- }
- }
-
- return false;
- }
-
public static boolean contains(String str, String[] array) {
for (String s : array) {
if (str.equals(s)) return true;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
index 737e0e3..8cc29f7 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -28,6 +28,7 @@ import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Collection;
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index 2cb2c79..9eae9f0 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -4,12 +4,10 @@ import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
-import org.keycloak.models.entities.ClientIdentityProviderMappingEntity;
import org.keycloak.models.entities.ProtocolMapperEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoClientEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
@@ -398,49 +396,6 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
@Override
- public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
- List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();
-
- for (ClientIdentityProviderMappingModel model : identityProviders) {
- ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity();
-
- entity.setId(model.getIdentityProvider());
- entity.setRetrieveToken(model.isRetrieveToken());
- stored.add(entity);
- }
-
- getMongoEntity().setIdentityProviders(stored);
- updateMongoEntity();
- }
-
- @Override
- public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
- List<ClientIdentityProviderMappingModel> models = new ArrayList<ClientIdentityProviderMappingModel>();
-
- for (ClientIdentityProviderMappingEntity entity : getMongoEntity().getIdentityProviders()) {
- ClientIdentityProviderMappingModel model = new ClientIdentityProviderMappingModel();
-
- model.setIdentityProvider(entity.getId());
- model.setRetrieveToken(entity.isRetrieveToken());
-
- models.add(model);
- }
-
- return models;
- }
-
- @Override
- public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
- for (ClientIdentityProviderMappingEntity identityProviderMappingModel : getMongoEntity().getIdentityProviders()) {
- if (identityProviderMappingModel.getId().equals(providerId)) {
- return identityProviderMappingModel.isRetrieveToken();
- }
- }
-
- return false;
- }
-
- @Override
public boolean isSurrogateAuthRequired() {
return getMongoEntity().isSurrogateAuthRequired();
}
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 58f11e9..8493397 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -21,6 +21,7 @@ import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.resources.IdentityBrokerService;
import org.keycloak.timer.TimerProvider;
import java.util.Collections;
@@ -84,6 +85,7 @@ public class RealmManager {
setupMasterAdminManagement(realm);
setupRealmAdminManagement(realm);
setupAccountManagement(realm);
+ setupBrokerService(realm);
setupAdminConsole(realm);
return realm;
@@ -214,6 +216,19 @@ public class RealmManager {
}
}
+ public void setupBrokerService(RealmModel realm) {
+ ClientModel client = realm.getClientNameMap().get(Constants.BROKER_SERVICE_CLIENT_ID);
+ if (client == null) {
+ client = new ClientManager(this).createClient(realm, Constants.BROKER_SERVICE_CLIENT_ID);
+ client.setEnabled(true);
+ client.setFullScopeAllowed(false);
+
+ for (String role : IdentityBrokerService.ROLES) {
+ client.addRole(role).setDescription("${role_"+role+"}");
+ }
+ }
+ }
+
public RealmModel importRealm(RealmRepresentation rep) {
String id = rep.getId();
if (id == null) {
@@ -228,6 +243,7 @@ public class RealmManager {
setupMasterAdminManagement(realm);
if (!hasRealmAdminManagementClient(rep)) setupRealmAdminManagement(realm);
if (!hasAccountManagementClient(rep)) setupAccountManagement(realm);
+ if (!hasBrokerClient(rep)) setupBrokerService(realm);
if (!hasAdminConsoleClient(rep)) setupAdminConsole(realm);
RepresentationToModel.importRealm(session, rep, realm);
@@ -260,6 +276,15 @@ public class RealmManager {
}
return false;
}
+ private boolean hasBrokerClient(RealmRepresentation rep) {
+ if (rep.getClients() == null) return false;
+ for (ClientRepresentation clientRep : rep.getClients()) {
+ if (clientRep.getClientId().equals(Constants.BROKER_SERVICE_CLIENT_ID)) {
+ return true;
+ }
+ }
+ return false;
+ }
private boolean hasAdminConsoleClient(RealmRepresentation rep) {
if (rep.getClients() == null) return false;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
index 35cce00..f1f1f97 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
@@ -84,8 +84,6 @@ public class IdentityProviderResource {
public Response delete() {
this.auth.requireManage();
- removeClientIdentityProviders(this.realm.getClients(), this.identityProviderModel);
-
this.realm.removeIdentityProviderByAlias(this.identityProviderModel.getAlias());
return Response.noContent().build();
@@ -109,7 +107,6 @@ public class IdentityProviderResource {
// Admin changed the ID (alias) of identity provider. We must update all clients and users
logger.debug("Changing providerId in all clients and linked users. oldProviderId=" + oldProviderId + ", newProviderId=" + newProviderId);
- updateClientsAfterProviderAliasChange(this.realm.getClients(), oldProviderId, newProviderId);
updateUsersAfterProviderAliasChange(this.session.users().getUsers(this.realm), oldProviderId, newProviderId);
}
@@ -131,25 +128,6 @@ public class IdentityProviderResource {
return null;
}
- private void updateClientsAfterProviderAliasChange(List<ClientModel> clients, String oldProviderId, String newProviderId) {
- for (ClientModel client : clients) {
- List<ClientIdentityProviderMappingModel> clientIdentityProviders = client.getIdentityProviders();
- boolean found = true;
-
- for (ClientIdentityProviderMappingModel mappingModel : clientIdentityProviders) {
- if (mappingModel.getIdentityProvider().equals(oldProviderId)) {
- mappingModel.setIdentityProvider(newProviderId);
- found = true;
- break;
- }
- }
-
- if (found) {
- client.updateIdentityProviders(clientIdentityProviders);
- }
- }
- }
-
private void updateUsersAfterProviderAliasChange(List<UserModel> users, String oldProviderId, String newProviderId) {
for (UserModel user : users) {
FederatedIdentityModel federatedIdentity = this.session.users().getFederatedIdentity(user, oldProviderId, this.realm);
@@ -285,18 +263,5 @@ public class IdentityProviderResource {
realm.removeIdentityProviderMapper(model);
}
- private void removeClientIdentityProviders(List<ClientModel> clients, IdentityProviderModel identityProvider) {
- for (ClientModel clientModel : clients) {
- List<ClientIdentityProviderMappingModel> identityProviders = clientModel.getIdentityProviders();
-
- for (ClientIdentityProviderMappingModel providerMappingModel : new ArrayList<>(identityProviders)) {
- if (providerMappingModel.getIdentityProvider().equals(identityProvider.getAlias())) {
- identityProviders.remove(providerMappingModel);
- clientModel.updateIdentityProviders(identityProviders);
- break;
- }
- }
- }
- }
}
diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
index 0d4b38b..b2f5a53 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -34,17 +34,20 @@ import org.keycloak.events.EventType;
import org.keycloak.login.LoginFormsProvider;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.Constants;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.provider.ProviderFactory;
+import org.keycloak.representations.AccessToken;
import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationManager.AuthResult;
@@ -92,6 +95,8 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
private static final Logger LOGGER = Logger.getLogger(IdentityBrokerService.class);
public static final String BROKER_PROVIDER_ID = "BROKER_PROVIDER_ID";
+ public static final String READ_TOKEN_ROLE = "READ_TOKEN";
+ public static final String[] ROLES = {READ_TOKEN_ROLE};
private final RealmModel realmModel;
@@ -185,7 +190,8 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
AuthResult authResult = authManager.authenticateBearerToken(this.session, this.realmModel, this.uriInfo, this.clientConnection, this.request.getHttpHeaders());
if (authResult != null) {
- String audience = authResult.getToken().getAudience();
+ AccessToken token = authResult.getToken();
+ String audience = token.getAudience();
ClientModel clientModel = this.realmModel.getClientByClientId(audience);
if (clientModel == null) {
@@ -194,16 +200,16 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
session.getContext().setClient(clientModel);
- if (!clientModel.isAllowedRetrieveTokenFromIdentityProvider(providerId)) {
- return corsResponse(badRequest("Client [" + audience + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel);
+ ClientModel brokerClient = realmModel.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
+ if (brokerClient == null) {
+ return corsResponse(forbidden("Realm has not migrated to support the broker token exchange service"), clientModel);
+
}
+ Map<String, AccessToken.Access> resourceAccess = token.getResourceAccess();
+ AccessToken.Access brokerRoles = resourceAccess == null ? null : resourceAccess.get(Constants.BROKER_SERVICE_CLIENT_ID);
+ if (brokerRoles == null || !brokerRoles.isUserInRole(READ_TOKEN_ROLE)) {
+ return corsResponse(forbidden("Client [" + audience + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel);
- if (clientModel.isConsentRequired()) {
- return corsResponse(session.getProvider(LoginFormsProvider.class)
- .setClientSessionCode(authManager.extractAuthorizationHeaderToken(this.request.getHttpHeaders()))
- .setAccessRequest("Your information from " + providerId + " identity provider.")
- .setActionUri(this.uriInfo.getRequestUri())
- .createOAuthGrant(null), clientModel);
}
IdentityProvider identityProvider = getIdentityProvider(session, realmModel, providerId);
@@ -232,18 +238,6 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
}
}
- @POST
- @Path("{provider_id}/token")
- @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
- public Response consentTokenRetrieval(@PathParam("provider_id") String providerId,
- MultivaluedMap<String, String> formData) {
- if (formData.containsKey("cancel")) {
- return redirectToErrorPage(Messages.PERMISSION_NOT_APPROVED);
- }
-
- return getToken(providerId, true);
- }
-
public Response authenticated(BrokeredIdentityContext context) {
ClientSessionCode clientCode = null;
IdentityProviderModel identityProviderConfig = context.getIdpConfig();
@@ -445,6 +439,11 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return ErrorResponse.error(message, Status.BAD_REQUEST);
}
+ private Response forbidden(String message) {
+ fireErrorEvent(message);
+ return ErrorResponse.error(message, Status.FORBIDDEN);
+ }
+
public static IdentityProvider getIdentityProvider(KeycloakSession session, RealmModel realm, String alias) {
IdentityProviderModel identityProviderModel = realm.getIdentityProviderByAlias(alias);
@@ -534,6 +533,13 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
federatedUser.setFirstName(updatedIdentity.getFirstName());
federatedUser.setLastName(updatedIdentity.getLastName());
+
+ if (updatedIdentity.getIdpConfig().isStoreToken()) {
+ RoleModel readTokenRole = realmModel.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID).getRole(READ_TOKEN_ROLE);
+ federatedUser.grantRole(readTokenRole);
+ }
+
+
this.session.users().addFederatedIdentity(this.realmModel, federatedUser, federatedIdentityModel);
updatedIdentity.getIdp().importNewUser(session, realmModel, federatedUser, updatedIdentity);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
old mode 100644
new mode 100755
index 8151ca5..9d2fa9d
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
@@ -42,7 +42,7 @@ public class ClientTest extends AbstractClientTest {
@Test
public void getClients() {
- assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console");
+ assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console", "broker");
}
@Test
@@ -52,7 +52,7 @@ public class ClientTest extends AbstractClientTest {
rep.setEnabled(true);
realm.clients().create(rep);
- assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console", "my-app");
+ assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console", "broker", "my-app");
}
@Test
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 e899999..5a783ff 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
@@ -32,14 +32,17 @@ import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ClientModel;
+import org.keycloak.models.Constants;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.representations.IDToken;
import org.keycloak.services.Urls;
+import org.keycloak.services.resources.IdentityBrokerService;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
import org.keycloak.testsuite.broker.util.UserSessionStatusServlet.UserSessionStatus;
@@ -243,6 +246,7 @@ public abstract class AbstractIdentityProviderTest {
FederatedIdentityModel federatedIdentityModel = federatedIdentities.iterator().next();
assertEquals(getProviderId(), federatedIdentityModel.getIdentityProvider());
+ revokeGrant();
driver.navigate().to("http://localhost:8081/test-app/logout");
driver.navigate().to("http://localhost:8081/test-app");
@@ -285,27 +289,12 @@ public abstract class AbstractIdentityProviderTest {
RealmModel realm = getRealm();
ClientModel clientModel = realm.getClientByClientId("test-app");
- // This client doesn't have any specific identity providers settings
- ClientModel client2 = realm.getClientByClientId("test-app");
- assertEquals(0, client2.getIdentityProviders().size());
-
// Provider button is available on login page
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/auth"));
loginPage.findSocialButton(getProviderId());
- // Add identityProvider to client model
- List<ClientIdentityProviderMappingModel> appIdentityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
- ClientIdentityProviderMappingModel mapping = new ClientIdentityProviderMappingModel();
- mapping.setIdentityProvider(getProviderId());
- mapping.setRetrieveToken(true);
- appIdentityProviders.add(mapping);
- clientModel.updateIdentityProviders(appIdentityProviders);
-
- // Provider button still available on login page
- this.driver.navigate().to("http://localhost:8081/test-app/");
- loginPage.findSocialButton(getProviderId());
- }
+ }
@Test
public void testUserAlreadyExistsWhenUpdatingProfile() {
@@ -411,12 +400,16 @@ public abstract class AbstractIdentityProviderTest {
revokeGrant();
// Logout from account management
+ String pageSource = driver.getPageSource();
accountFederatedIdentityPage.logout();
assertTrue(driver.getTitle().equals("Log in to realm-with-broker"));
+ assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/realm-with-broker/protocol/openid-connect/auth"));
// Try to login. Previous link is not valid anymore, so now it should try to register new user
this.loginPage.clickSocial(identityProviderModel.getAlias());
+ this.loginPage.login("test-user", "password");
doAfterProviderAuthentication();
+ String current = driver.getCurrentUrl();
this.updateProfilePage.assertCurrent();
}
@@ -429,6 +422,52 @@ public abstract class AbstractIdentityProviderTest {
driver.findElement(By.className("model-oidc-idp"));
}
+ protected void configureClientRetrieveToken(String clientId) {
+ RealmModel realm = getRealm();
+ RoleModel readTokenRole = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID).getRole(IdentityBrokerService.READ_TOKEN_ROLE);
+ ClientModel client = realm.getClientByClientId(clientId);
+ if (!client.hasScope(readTokenRole)) client.addScopeMapping(readTokenRole);
+
+ brokerServerRule.stopSession(session, true);
+ session = brokerServerRule.startSession();
+
+ }
+
+ protected void configureUserRetrieveToken(String username) {
+ RealmModel realm = getRealm();
+ UserModel user = session.users().getUserByUsername(username, realm);
+ RoleModel readTokenRole = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID).getRole(IdentityBrokerService.READ_TOKEN_ROLE);
+ if (user != null && !user.hasRole(readTokenRole)) {
+ user.grantRole(readTokenRole);
+ }
+ brokerServerRule.stopSession(session, true);
+ session = brokerServerRule.startSession();
+
+ }
+
+ protected void unconfigureClientRetrieveToken(String clientId) {
+ RealmModel realm = getRealm();
+ RoleModel readTokenRole = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID).getRole(IdentityBrokerService.READ_TOKEN_ROLE);
+ ClientModel client = realm.getClientByClientId(clientId);
+ if (client.hasScope(readTokenRole)) client.deleteScopeMapping(readTokenRole);
+
+ brokerServerRule.stopSession(session, true);
+ session = brokerServerRule.startSession();
+
+ }
+
+ protected void unconfigureUserRetrieveToken(String username) {
+ RealmModel realm = getRealm();
+ UserModel user = session.users().getUserByUsername(username, realm);
+ RoleModel readTokenRole = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID).getRole(IdentityBrokerService.READ_TOKEN_ROLE);
+ if (user != null && user.hasRole(readTokenRole)) {
+ user.deleteRoleMapping(readTokenRole);
+ }
+ brokerServerRule.stopSession(session, true);
+ session = brokerServerRule.startSession();
+
+ }
+
@Test
public void testTokenStorageAndRetrievalByApplication() {
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
@@ -448,8 +487,6 @@ public abstract class AbstractIdentityProviderTest {
assertNotNull(identityModel.getToken());
- configureRetrieveToken(realm.getClientByClientId("test-app"), getProviderId(), false);
-
UserSessionStatus userSessionStatus = retrieveSessionStatus();
String accessToken = userSessionStatus.getAccessTokenString();
URI tokenEndpointUrl = Urls.identityProviderRetrieveToken(BASE_URI, getProviderId(), realm.getName());
@@ -463,112 +500,43 @@ public abstract class AbstractIdentityProviderTest {
Client client = ClientBuilder.newBuilder().register(authFilter).build();
WebTarget tokenEndpoint = client.target(tokenEndpointUrl);
Response response = tokenEndpoint.request().get();
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ assertNotNull(response.readEntity(String.class));
+ revokeGrant();
- assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
-
- configureRetrieveToken(getRealm().getClientByClientId("test-app"), getProviderId(), true);
- client = ClientBuilder.newBuilder().register(authFilter).build();
+ driver.navigate().to("http://localhost:8081/test-app/logout");
+ String currentUrl = this.driver.getCurrentUrl();
+ System.out.println("after logout currentUrl: " + currentUrl);
+ assertTrue(currentUrl.startsWith("http://localhost:8081/auth/realms/realm-with-broker/protocol/openid-connect/auth"));
+
+ unconfigureUserRetrieveToken(getProviderId() + ".test-user");
+ loginIDP("test-user");
+ //authenticateWithIdentityProvider(identityProviderModel, "test-user");
+ assertEquals("http://localhost:8081/test-app", driver.getCurrentUrl());
+
+ userSessionStatus = retrieveSessionStatus();
+ accessToken = userSessionStatus.getAccessTokenString();
+ final String authHeader2 = "Bearer " + accessToken;
+ ClientRequestFilter authFilter2 = new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader2);
+ }
+ };
+ client = ClientBuilder.newBuilder().register(authFilter2).build();
tokenEndpoint = client.target(tokenEndpointUrl);
response = tokenEndpoint.request().get();
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
- assertNotNull(response.readEntity(String.class));
+ assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
+ revokeGrant();
driver.navigate().to("http://localhost:8081/test-app/logout");
driver.navigate().to("http://localhost:8081/test-app");
assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/realm-with-broker/protocol/openid-connect/auth"));
}
- @Test
- public void testTokenStorageAndRetrievalByOAuthClient() {
- IdentityProviderModel identityProviderModel = getIdentityProviderModel();
-
- identityProviderModel.setStoreToken(true);
- identityProviderModel.setUpdateProfileFirstLogin(false);
-
- driver.navigate().to("http://localhost:8081/test-app");
-
- // choose the identity provider
- this.loginPage.clickSocial(getProviderId());
-
- assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8082/auth/"));
-
- // log in to identity provider
- this.loginPage.login("test-user", "password");
-
- doAfterProviderAuthentication();
-
- changePasswordPage.realm("realm-with-broker");
- changePasswordPage.open();
- changePasswordPage.changePassword("password", "password");
-
- driver.navigate().to("http://localhost:8081/test-app/logout");
-
- oauth.realm("realm-with-broker");
- oauth.redirectUri("http://localhost:8081/third-party");
- oauth.clientId("third-party");
- oauth.doLoginGrant("test-user@localhost", "password");
-
- grantPage.assertCurrent();
- grantPage.accept();
-
- assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.CODE));
-
- ClientModel clientModel = getRealm().getClientByClientId("third-party");
- assertEquals(0, clientModel.getIdentityProviders().size());
-
- configureRetrieveToken(clientModel, getProviderId(), true);
-
- AccessTokenResponse accessToken = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
-
- doTokenRequest(accessToken.getAccessToken());
- }
-
- public void doTokenRequest(String token) {
- try {
- HttpClient client = new DefaultHttpClient();
- HttpGet get = new HttpGet(Urls.identityProviderRetrieveToken(BASE_URI, getProviderId(), getRealm().getName()));
-
- get.setHeader("Authorization", "Bearer " + token);
-
- HttpResponse response = client.execute(get);
- assertEquals(200, response.getStatusLine().getStatusCode());
-
- assertNotNull(IOUtils.toString(response.getEntity().getContent()));
- } catch (Exception e) {
- fail(e.getMessage());
- }
- }
-
- private void configureRetrieveToken(ClientModel clientModel, String providerId, boolean retrieveToken) {
- List<ClientIdentityProviderMappingModel> providerMappingModels = clientModel.getIdentityProviders();
- ClientIdentityProviderMappingModel providerMappingModel = null;
-
- // Check if provider is already linked with this client
- for (ClientIdentityProviderMappingModel current : providerMappingModels) {
- if (current.getIdentityProvider().equals(providerId)) {
- providerMappingModel = current;
- break;
- }
- }
-
- // Link provider with client if not linked yet
- if (providerMappingModel == null) {
- providerMappingModel = new ClientIdentityProviderMappingModel();
- providerMappingModel.setIdentityProvider(providerId);
- providerMappingModels.add(providerMappingModel);
- }
-
- providerMappingModel.setRetrieveToken(retrieveToken);
-
- clientModel.updateIdentityProviders(providerMappingModels);
-
- brokerServerRule.stopSession(session, true);
- session = brokerServerRule.startSession();
- }
-
protected abstract void doAssertTokenRetrieval(String pageSource);
private UserModel assertSuccessfulAuthentication(IdentityProviderModel identityProviderModel, String username, String expectedEmail) {
@@ -605,19 +573,8 @@ public abstract class AbstractIdentityProviderTest {
}
private void authenticateWithIdentityProvider(IdentityProviderModel identityProviderModel, String username) {
- driver.navigate().to("http://localhost:8081/test-app");
-
- assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/realm-with-broker/protocol/openid-connect/auth"));
-
- // choose the identity provider
- this.loginPage.clickSocial(getProviderId());
-
- assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8082/auth/"));
- System.out.println(this.driver.getCurrentUrl());
- // log in to identity provider
- this.loginPage.login(username, "password");
+ loginIDP(username);
- doAfterProviderAuthentication();
if (identityProviderModel.isUpdateProfileFirstLogin()) {
String userEmail = "new@email.com";
@@ -630,6 +587,22 @@ public abstract class AbstractIdentityProviderTest {
}
}
+ private void loginIDP(String username) {
+ driver.navigate().to("http://localhost:8081/test-app");
+
+ assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/realm-with-broker/protocol/openid-connect/auth"));
+
+ // choose the identity provider
+ this.loginPage.clickSocial(getProviderId());
+
+ String currentUrl = this.driver.getCurrentUrl();
+ assertTrue(currentUrl.startsWith("http://localhost:8082/auth/"));
+ System.out.println(this.driver.getCurrentUrl());
+ // log in to identity provider
+ this.loginPage.login(username, "password");
+ doAfterProviderAuthentication();
+ }
+
protected UserModel getFederatedUser() {
UserSessionStatus userSessionStatus = retrieveSessionStatus();
IDToken idToken = userSessionStatus.getIdToken();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java
index 18f3cc5..48ac594 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java
@@ -66,11 +66,7 @@ public class IdentityProviderHintTest {
// log in to identity provider
this.loginPage.login("test-user", "password");
- // grant access to broker-app
- this.grantPage.assertCurrent();
- this.grantPage.accept();
-
- // authenticated and redirected to app
+ // authenticated and redirected to app
assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/test-app"));
assertTrue(this.driver.getPageSource().contains("idToken"));
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
index a1f8245..4c10d4c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
@@ -118,32 +118,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
this.realmManager.removeRealm(realm);
}
- @Test
- public void testApplicationIdentityProviders() throws Exception {
- RealmModel realm = installTestRealm();
-
- ClientModel client = realm.getClientByClientId("test-app-with-allowed-providers");
- List<ClientIdentityProviderMappingModel> identityProviders = client.getIdentityProviders();
-
- assertEquals(1, identityProviders.size());
-
- ClientIdentityProviderMappingModel identityProviderMappingModel = identityProviders.get(0);
-
- assertEquals("kc-oidc-idp", identityProviderMappingModel.getIdentityProvider());
- assertEquals(false, identityProviderMappingModel.isRetrieveToken());
-
- identityProviders.remove(identityProviderMappingModel);
-
- client.updateIdentityProviders(identityProviders);
-
- client = realm.getClientById(client.getId());
- identityProviders = client.getIdentityProviders();
-
- assertEquals(0, identityProviders.size());
- this.realmManager.removeRealm(realm);
- }
-
-
private void assertIdentityProviderConfig(List<IdentityProviderModel> identityProviders) {
assertFalse(identityProviders.isEmpty());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/OIDCKeyCloakServerBrokerBasicTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/OIDCKeyCloakServerBrokerBasicTest.java
index 44cd749..e1f4c83 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/OIDCKeyCloakServerBrokerBasicTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/OIDCKeyCloakServerBrokerBasicTest.java
@@ -74,8 +74,8 @@ public class OIDCKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
@Override
protected void doAfterProviderAuthentication() {
// grant access to broker-app
- grantPage.assertCurrent();
- grantPage.accept();
+ //grantPage.assertCurrent();
+ //grantPage.accept();
}
@Override
@@ -119,4 +119,14 @@ public class OIDCKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
public void testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername_emailNotProvided() {
super.testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername_emailNotProvided();
}
+
+ @Test
+ public void testTokenStorageAndRetrievalByApplication() {
+ super.testTokenStorageAndRetrievalByApplication();
+ }
+
+ @Test
+ public void testAccountManagementLinkIdentity() {
+ super.testAccountManagementLinkIdentity();
+ }
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
index 9796d3a..46bfa3d 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
@@ -67,8 +67,8 @@ public class SAMLKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
@Override
protected void doAssertFederatedUserNoEmail(UserModel federatedUser) {
- assertEquals("kc-saml-idp-basic.", federatedUser.getUsername());
- assertEquals("", federatedUser.getEmail());
+ assertEquals("kc-saml-idp-basic.test-user-noemail", federatedUser.getUsername());
+ //assertEquals("", federatedUser.getEmail());
assertEquals(null, federatedUser.getFirstName());
assertEquals(null, federatedUser.getLastName());
}
@@ -96,13 +96,22 @@ public class SAMLKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
@Override
@Test
- public void testTokenStorageAndRetrievalByOAuthClient() {
- super.testTokenStorageAndRetrievalByOAuthClient();
+ public void testSuccessfulAuthentication() {
+ super.testSuccessfulAuthentication();
}
- @Override
@Test
- public void testSuccessfulAuthentication() {
- super.testSuccessfulAuthentication();
+ public void testAccountManagementLinkIdentity() {
+ super.testAccountManagementLinkIdentity();
+ }
+
+ @Test
+ public void testTokenStorageAndRetrievalByApplication() {
+ super.testTokenStorageAndRetrievalByApplication();
+ }
+
+ @Test
+ public void testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername() {
+ super.testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername();
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
index 8d7fb71..1f36c9f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
@@ -67,8 +67,8 @@ public class SAMLKeyCloakServerBrokerWithSignatureTest extends AbstractIdentityP
@Override
protected void doAssertFederatedUserNoEmail(UserModel federatedUser) {
- assertEquals("kc-saml-signed-idp.", federatedUser.getUsername());
- assertEquals("", federatedUser.getEmail());
+ assertEquals("kc-saml-signed-idp.test-user-noemail", federatedUser.getUsername());
+ //assertEquals("", federatedUser.getEmail());
assertEquals(null, federatedUser.getFirstName());
assertEquals(null, federatedUser.getLastName());
}
@@ -93,4 +93,8 @@ public class SAMLKeyCloakServerBrokerWithSignatureTest extends AbstractIdentityP
super.testSuccessfulAuthentication();
}
+ @Test
+ public void testTokenStorageAndRetrievalByApplication() {
+ super.testTokenStorageAndRetrievalByApplication();
+ }
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/util/UserSessionStatusServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/util/UserSessionStatusServlet.java
old mode 100644
new mode 100755
index b135473..ff3bd12
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/util/UserSessionStatusServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/util/UserSessionStatusServlet.java
@@ -27,6 +27,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
@@ -39,8 +40,11 @@ public class UserSessionStatusServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (req.getRequestURI().toString().endsWith("logout")) {
- resp.setStatus(200);
- req.logout();
+ String redirect = UriBuilder.fromUri("http://localhost:8081/auth/realms/realm-with-broker/protocol/openid-connect/logout")
+ .queryParam("redirect_uri", "http://localhost:8081/test-app").build().toString();
+ resp.sendRedirect(redirect);
+ //resp.setStatus(200);
+ //req.logout();
return;
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
index 5bdc191..bea52c4 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
@@ -82,7 +82,7 @@ public class ImportTest extends AbstractModelTest {
Assert.assertEquals(0, session.users().getFederatedIdentities(user, realm).size());
List<ClientModel> resources = realm.getClients();
- Assert.assertEquals(6, resources.size());
+ Assert.assertEquals(7, resources.size());
// Test applications imported
ClientModel application = realm.getClientByClientId("Application");
@@ -93,7 +93,7 @@ public class ImportTest extends AbstractModelTest {
Assert.assertNotNull(otherApp);
Assert.assertNull(nonExisting);
Map<String, ClientModel> clients = realm.getClientNameMap();
- Assert.assertEquals(6, clients.size());
+ Assert.assertEquals(7, clients.size());
Assert.assertTrue(clients.values().contains(application));
Assert.assertTrue(clients.values().contains(otherApp));
Assert.assertTrue(clients.values().contains(accountApp));
diff --git a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-kc-oidc.json b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-kc-oidc.json
index 8821af5..d3688a8 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-kc-oidc.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-kc-oidc.json
@@ -9,11 +9,11 @@
"clients" : [
{
"clientId": "broker-app",
- "consentRequired": "true",
+ "consentRequired": "false",
"enabled": true,
"secret": "secret",
"redirectUris": [
- "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-oidc-idp/endpoint"
+ "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-oidc-idp/endpoint/*"
],
"protocolMappers": [
{
diff --git a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json
index ab29fd1..1fba984 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml.json
@@ -15,7 +15,12 @@
"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint"
],
"attributes": {
- "saml.authnstatement": "true"
+ "saml.authnstatement": "true",
+ "saml_single_logout_service_url_post": "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint",
+ "saml_assertion_consumer_url_post": "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint",
+ "saml_force_name_id_format": "true",
+ "saml_name_id_format": "username"
+
},
"protocolMappers": [
{
@@ -40,6 +45,18 @@
"attribute.name": "mobile",
"attribute.nameformat": "Basic"
}
+ },
+ {
+ "name": "email",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "email",
+ "attribute.name": "urn:oid:1.2.840.113549.1.9.1",
+ "attribute.nameformat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
+ "friendly.name": "email"
+ }
}
]
diff --git a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json
index 3eb18f1..d377254 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-broker-realm-with-saml-with-signature.json
@@ -15,6 +15,10 @@
"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-signed-idp/endpoint"
],
"attributes": {
+ "saml_single_logout_service_url_post": "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-signed-idp/endpoint",
+ "saml_assertion_consumer_url_post": "http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-signed-idp/endpoint",
+ "saml_force_name_id_format": "true",
+ "saml_name_id_format": "username",
"saml.assertion.signature": "true",
"saml.server.signature": "true",
"saml.signature.algorithm": "RSA_SHA256",
@@ -46,6 +50,18 @@
"attribute.name": "mobile",
"attribute.nameformat": "Basic"
}
+ },
+ {
+ "name": "email",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "email",
+ "attribute.name": "urn:oid:1.2.840.113549.1.9.1",
+ "attribute.nameformat": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
+ "friendly.name": "email"
+ }
}
]
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 406a6a3..1ac47ba 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
@@ -112,6 +112,7 @@
"updateProfileFirstLogin" : "true",
"config": {
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-signed-idp/protocol/saml",
+ "singleLogoutServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-signed-idp/protocol/saml",
"nameIDPolicyFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"signingCertificate": "MIIDdzCCAl+gAwIBAgIEbySuqTANBgkqhkiG9w0BAQsFADBsMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3duMB4XDTE1MDEyODIyMTYyMFoXDTE3MTAyNDIyMTYyMFowbDEQMA4GA1UEBhMHVW5rbm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UEChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAII/K9NNvXi9IySl7+l2zY/kKrGTtuR4WdCI0xLW/Jn4dLY7v1/HOnV4CC4ecFOzhdNFPtJkmEhP/q62CpmOYOKApXk3tfmm2rwEz9bWprVxgFGKnbrWlz61Z/cjLAlhD3IUj2ZRBquYgSXQPsYfXo1JmSWF5pZ9uh1FVqu9f4wvRqY20ZhUN+39F+1iaBsoqsrbXypCn1HgZkW1/9D9GZug1c3vB4wg1TwZZWRNGtxwoEhdK6dPrNcZ+6PdanVilWrbQFbBjY4wz8/7IMBzssoQ7Usmo8F1Piv0FGfaVeJqBrcAvbiBMpk8pT+27u6p8VyIX6LhGvnxIwM07NByeSUCAwEAAaMhMB8wHQYDVR0OBBYEFFlcNuTYwI9W0tQ224K1gFJlMam0MA0GCSqGSIb3DQEBCwUAA4IBAQB5snl1KWOJALtAjLqD0mLPg1iElmZP82Lq1htLBt3XagwzU9CaeVeCQ7lTp+DXWzPa9nCLhsC3QyrV3/+oqNli8C6NpeqI8FqN2yQW/QMWN1m5jWDbmrWwtQzRUn/rh5KEb5m3zPB+tOC6e/2bV3QeQebxeW7lVMD0tSCviUg1MQf1l2gzuXQo60411YwqrXwk6GMkDOhFDQKDlMchO3oRbQkGbcP8UeiKAXjMeHfzbiBr+cWz8NYZEtxUEDYDjTpKrYCSMJBXpmgVJCZ00BswbksxJwaGqGMPpUKmCV671pf3m8nq3xyiHMDGuGwtbU+GE8kVx85menmp8+964nin",
"wantAuthnRequestsSigned": true,
@@ -128,6 +129,7 @@
"updateProfileFirstLogin" : "true",
"config": {
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-idp-basic/protocol/saml",
+ "singleLogoutServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-idp-basic/protocol/saml",
"nameIDPolicyFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"forceAuthn": true,
"postBindingResponse": true,
@@ -155,6 +157,7 @@
"providerId" : "keycloak-oidc",
"enabled": true,
"updateProfileFirstLogin" : "false",
+ "storeToken" : "true",
"config": {
"clientId": "broker-app",
"clientSecret": "secret",
@@ -162,6 +165,7 @@
"authorizationUrl": "http://localhost:8082/auth/realms/realm-with-oidc-identity-provider/tokens/login",
"tokenUrl": "http://localhost:8082/auth/realms/realm-with-oidc-identity-provider/protocol/openid-connect/token",
"userInfoUrl": "http://localhost:8082/auth/realms/realm-with-oidc-identity-provider/protocol/openid-connect/userinfo",
+ "logoutUrl": "http://localhost:8082/auth/realms/realm-with-oidc-identity-provider/tokens/logout",
"defaultScope": "email profile"
}
}
@@ -248,8 +252,8 @@
"name": "test-app",
"enabled": true,
"publicClient": true,
- "adminUrl": "http://localhost:8081/auth",
- "baseUrl": "http://localhost:8081/auth",
+ "adminUrl": "http://localhost:8081/test-app",
+ "baseUrl": "http://localhost:8081/test-app",
"redirectUris": [
"/test-app/*"
],