diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
index 71fc2c4be4..6139c3d931 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
@@ -5,14 +5,21 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
+
+
diff --git a/core/src/main/java/org/keycloak/representations/UserClaimSet.java b/core/src/main/java/org/keycloak/representations/UserClaimSet.java
old mode 100644
new mode 100755
index c6472691a1..4e8f1f9f57
--- a/core/src/main/java/org/keycloak/representations/UserClaimSet.java
+++ b/core/src/main/java/org/keycloak/representations/UserClaimSet.java
@@ -24,6 +24,75 @@ import org.codehaus.jackson.annotate.JsonProperty;
*/
public class UserClaimSet {
+ public static class AddressClaimSet {
+ @JsonProperty("formatted")
+ protected String formattedAddress;
+
+ @JsonProperty("street_address")
+ protected String streetAddress;
+
+ @JsonProperty("locality")
+ protected String locality;
+
+ @JsonProperty("region")
+ protected String region;
+
+ @JsonProperty("postal_code")
+ protected String postalCode;
+
+ @JsonProperty("country")
+ protected String country;
+
+ public String getFormattedAddress() {
+ return this.formattedAddress;
+ }
+
+ public void setFormattedAddress(String formattedAddress) {
+ this.formattedAddress = formattedAddress;
+ }
+
+ public String getStreetAddress() {
+ return this.streetAddress;
+ }
+
+ public void setStreetAddress(String streetAddress) {
+ this.streetAddress = streetAddress;
+ }
+
+ public String getLocality() {
+ return this.locality;
+ }
+
+ public void setLocality(String locality) {
+ this.locality = locality;
+ }
+
+ public String getRegion() {
+ return this.region;
+ }
+
+ public void setRegion(String region) {
+ this.region = region;
+ }
+
+ public String getPostalCode() {
+ return this.postalCode;
+ }
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getCountry() {
+ return this.country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ }
+
@JsonProperty("sub")
protected String sub;
@@ -79,29 +148,11 @@ public class UserClaimSet {
protected Boolean phoneNumberVerified;
@JsonProperty("address")
- protected String address;
+ protected AddressClaimSet address;
@JsonProperty("updated_at")
protected Long updatedAt;
- @JsonProperty("formatted")
- protected String formattedAddress;
-
- @JsonProperty("street_address")
- protected String streetAddress;
-
- @JsonProperty("locality")
- protected String locality;
-
- @JsonProperty("region")
- protected String region;
-
- @JsonProperty("postal_code")
- protected String postalCode;
-
- @JsonProperty("country")
- protected String country;
-
@JsonProperty("claims_locales")
protected String claimsLocales;
@@ -249,11 +300,11 @@ public class UserClaimSet {
this.phoneNumberVerified = phoneNumberVerified;
}
- public String getAddress() {
- return this.address;
+ public AddressClaimSet getAddress() {
+ return address;
}
- public void setAddress(String address) {
+ public void setAddress(AddressClaimSet address) {
this.address = address;
}
@@ -273,54 +324,6 @@ public class UserClaimSet {
this.sub = sub;
}
- public String getFormattedAddress() {
- return this.formattedAddress;
- }
-
- public void setFormattedAddress(String formattedAddress) {
- this.formattedAddress = formattedAddress;
- }
-
- public String getStreetAddress() {
- return this.streetAddress;
- }
-
- public void setStreetAddress(String streetAddress) {
- this.streetAddress = streetAddress;
- }
-
- public String getLocality() {
- return this.locality;
- }
-
- public void setLocality(String locality) {
- this.locality = locality;
- }
-
- public String getRegion() {
- return this.region;
- }
-
- public void setRegion(String region) {
- this.region = region;
- }
-
- public String getPostalCode() {
- return this.postalCode;
- }
-
- public void setPostalCode(String postalCode) {
- this.postalCode = postalCode;
- }
-
- public String getCountry() {
- return this.country;
- }
-
- public void setCountry(String country) {
- this.country = country;
- }
-
public String getClaimsLocales() {
return this.claimsLocales;
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 0e42a40ba7..9ca74f07d0 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -30,7 +30,7 @@ public class ApplicationRepresentation {
protected Integer nodeReRegistrationTimeout;
protected Map registeredNodes;
protected List allowedIdentityProviders;
- protected Set protocolClaimMappings;
+ protected List protocolMappers;
public String getId() {
return id;
@@ -200,11 +200,11 @@ public class ApplicationRepresentation {
this.allowedIdentityProviders = allowedIdentityProviders;
}
- public Set getProtocolClaimMappings() {
- return protocolClaimMappings;
+ public List getProtocolMappers() {
+ return protocolMappers;
}
- public void setProtocolClaimMappings(Set protocolClaimMappings) {
- this.protocolClaimMappings = protocolClaimMappings;
+ public void setProtocolMappers(List protocolMappers) {
+ this.protocolMappers = protocolMappers;
}
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ClientProtocolMappingRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClientProtocolMappingRepresentation.java
new file mode 100755
index 0000000000..e5252b1c16
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/ClientProtocolMappingRepresentation.java
@@ -0,0 +1,26 @@
+package org.keycloak.representations.idm;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class ClientProtocolMappingRepresentation {
+ protected String protocol;
+ protected String name;
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
index dcb6ba805e..aa095a7000 100755
--- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
@@ -24,7 +24,7 @@ public class OAuthClientRepresentation {
protected Boolean fullScopeAllowed;
protected Boolean frontchannelLogout;
protected List allowedIdentityProviders;
- protected Set protocolClaimMappings;
+ protected List protocolMappers;
public String getId() {
@@ -147,11 +147,11 @@ public class OAuthClientRepresentation {
this.allowedIdentityProviders = allowedIdentityProviders;
}
- public Set getProtocolClaimMappings() {
- return protocolClaimMappings;
+ public List getProtocolMappers() {
+ return protocolMappers;
}
- public void setProtocolClaimMappings(Set protocolClaimMappings) {
- this.protocolClaimMappings = protocolClaimMappings;
+ public void setProtocolMappers(List protocolMappers) {
+ this.protocolMappers = protocolMappers;
}
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 9b655dc15a..dc5ada6a6d 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -1,6 +1,7 @@
package org.keycloak.representations.idm;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -64,7 +65,7 @@ public class RealmRepresentation {
protected List eventsListeners;
private List identityProviders;
private List claimTypes;
- private List protocolClaimMappings;
+ private List protocolMappers;
private Boolean identityFederationEnabled;
public String getId() {
@@ -492,11 +493,16 @@ public class RealmRepresentation {
this.claimTypes = claimTypes;
}
- public List getProtocolClaimMappings() {
- return protocolClaimMappings;
+ public List getProtocolMappers() {
+ return protocolMappers;
}
- public void setProtocolClaimMappings(List protocolClaimMappings) {
- this.protocolClaimMappings = protocolClaimMappings;
+ public void addProtocolMapper(ProtocolMapperRepresentation rep) {
+ if (protocolMappers == null) protocolMappers = new LinkedList();
+ protocolMappers.add(rep);
+ }
+
+ public void setProtocolMappers(List protocolMappers) {
+ this.protocolMappers = protocolMappers;
}
}
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 243de4dc43..5354d04225 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -107,4 +107,5 @@ public interface ClientModel {
Set getProtocolMappers();
void addProtocolMappers(Set mapperIds);
void removeProtocolMappers(Set mapperIds);
+ void setProtocolMappers(Set mapperIds);
}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index badc6bdbb9..f70f8255a5 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -1,6 +1,7 @@
package org.keycloak.models;
import org.keycloak.enums.SslRequired;
+import org.keycloak.provider.ProviderEvent;
import java.security.Key;
import java.security.PrivateKey;
@@ -15,6 +16,19 @@ import java.util.Set;
* @version $Revision: 1 $
*/
public interface RealmModel extends RoleContainerModel {
+ interface RealmCreationEvent extends ProviderEvent {
+ RealmModel getCreatedRealm();
+ }
+ interface ClientCreationEvent extends ProviderEvent {
+ RealmModel getCreatedRealm();
+ ClientModel getCreatedClient();
+ }
+ interface ApplicationCreationEvent extends ClientCreationEvent {
+ ApplicationModel getCreatedApplication();
+ }
+ interface OAuthClientCreationEvent extends ClientCreationEvent {
+ OAuthClientModel getCreatedOAuthClient();
+ }
String getId();
@@ -235,6 +249,7 @@ public interface RealmModel extends RoleContainerModel {
void removeProtocolMapper(ProtocolMapperModel mapping);
void updateProtocolMapper(ProtocolMapperModel mapping);
public ProtocolMapperModel getProtocolMapperById(String id);
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name);
}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmProvider.java b/model/api/src/main/java/org/keycloak/models/RealmProvider.java
index f2454d41bd..58328b2cb5 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmProvider.java
@@ -10,9 +10,6 @@ import java.util.List;
* @version $Revision: 1 $
*/
public interface RealmProvider extends Provider {
- public interface RealmCreationEvent extends ProviderEvent {
- RealmModel getCreatedRealm();
- }
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
index 1cfbcfe32d..3d43feeb3d 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
@@ -30,7 +30,7 @@ public class ClientEntity extends AbstractIdentifiableEntity {
private List redirectUris = new ArrayList();
private List scopeIds = new ArrayList();
private List allowedIdentityProviders = new ArrayList();
- private Set protocolClaimMappings = new HashSet();
+ private Set protocolMappers = new HashSet();
public String getName() {
return name;
@@ -152,11 +152,11 @@ public class ClientEntity extends AbstractIdentifiableEntity {
this.allowedIdentityProviders = allowedIdentityProviders;
}
- public Set getProtocolClaimMappings() {
- return protocolClaimMappings;
+ public Set getProtocolMappers() {
+ return protocolMappers;
}
- public void setProtocolClaimMappings(Set protocolClaimMappings) {
- this.protocolClaimMappings = protocolClaimMappings;
+ public void setProtocolMappers(Set protocolMappers) {
+ this.protocolMappers = protocolMappers;
}
}
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 69d5477f07..522c96572b 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
@@ -19,6 +19,7 @@ import org.keycloak.models.UserSessionModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.ClaimTypeRepresentation;
+import org.keycloak.representations.idm.ClientProtocolMappingRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@@ -158,7 +159,7 @@ public class ModelToRepresentation {
}
for (ProtocolMapperModel mapping : realm.getProtocolMappers()) {
- rep.getProtocolClaimMappings().add(toRepresentation(mapping));
+ rep.addProtocolMapper(toRepresentation(mapping));
}
return rep;
@@ -266,9 +267,13 @@ public class ModelToRepresentation {
}
if (!applicationModel.getProtocolMappers().isEmpty()) {
- Set mappings = new HashSet();
- for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) mappings.add(model.getId());
- rep.setProtocolClaimMappings(mappings);
+ List mappings = new LinkedList();
+ for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) {
+ ClientProtocolMappingRepresentation map = new ClientProtocolMappingRepresentation();
+ map.setProtocol(model.getProtocol());
+ map.setName(model.getName());
+ }
+ rep.setProtocolMappers(mappings);
}
return rep;
@@ -301,10 +306,15 @@ public class ModelToRepresentation {
}
if (!model.getProtocolMappers().isEmpty()) {
- Set mappings = new HashSet();
- for (ProtocolMapperModel mappingMoel : model.getProtocolMappers()) mappings.add(mappingMoel.getId());
- rep.setProtocolClaimMappings(mappings);
+ List mappings = new LinkedList();
+ for (ProtocolMapperModel mapping : model.getProtocolMappers()) {
+ ClientProtocolMappingRepresentation map = new ClientProtocolMappingRepresentation();
+ map.setProtocol(mapping.getProtocol());
+ map.setName(mapping.getName());
+ }
+ rep.setProtocolMappers(mappings);
}
+
return rep;
}
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 2fb49af311..9e152b8137 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
@@ -23,6 +23,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.ClaimTypeRepresentation;
+import org.keycloak.representations.idm.ClientProtocolMappingRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@@ -460,10 +461,19 @@ public class RepresentationToModel {
applicationModel.setAllowedClaimsMask(ClaimMask.ALL);
}
- if (resourceRep.getProtocolClaimMappings() != null) {
- applicationModel.addProtocolMappers(resourceRep.getProtocolClaimMappings());
+ if (resourceRep.getProtocolMappers() != null) {
+ Set ids = new HashSet();
+ for (ClientProtocolMappingRepresentation map : resourceRep.getProtocolMappers()) {
+ ProtocolMapperModel mapperModel = applicationModel.getRealm().getProtocolMapperByName(map.getProtocol(), map.getName());
+ if (mapperModel != null) {
+ ids.add(mapperModel.getId());
+ }
+
+ }
+ applicationModel.setProtocolMappers(ids);
}
+
return applicationModel;
}
@@ -637,8 +647,16 @@ public class RepresentationToModel {
model.updateAllowedIdentityProviders(rep.getAllowedIdentityProviders());
}
- if (rep.getProtocolClaimMappings() != null) {
- model.addProtocolMappers(rep.getProtocolClaimMappings());
+ if (rep.getProtocolMappers() != null) {
+ Set ids = new HashSet();
+ for (ClientProtocolMappingRepresentation map : rep.getProtocolMappers()) {
+ ProtocolMapperModel mapperModel = model.getRealm().getProtocolMapperByName(map.getProtocol(), map.getName());
+ if (mapperModel != null) {
+ ids.add(mapperModel.getId());
+ }
+
+ }
+ model.setProtocolMappers(ids);
}
}
@@ -773,13 +791,17 @@ public class RepresentationToModel {
}
private static void importProtocolMappers(RealmRepresentation rep, RealmModel newRealm) {
- if (rep.getProtocolClaimMappings() != null) {
+ if (rep.getProtocolMappers() != null) {
// we make sure we don't recreate mappers that are automatically created by the protocol providers.
- for (ProtocolMapperRepresentation representation : rep.getProtocolClaimMappings()) {
- if (representation.getId() == null || newRealm.getProtocolMapperById(representation.getId()) == null) {
+ Set mappers = newRealm.getProtocolMappers();
+ for (ProtocolMapperRepresentation representation : rep.getProtocolMappers()) {
+ ProtocolMapperModel existing = newRealm.getProtocolMapperByName(representation.getProtocol(), representation.getName());
+ if (existing == null) {
newRealm.addProtocolMapper(toModel(representation));
} else {
- newRealm.updateProtocolMapper(toModel(representation));
+ ProtocolMapperModel mapping = toModel(representation);
+ mapping.setId(existing.getId());
+ newRealm.updateProtocolMapper(mapping);
}
}
}
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 83f5490089..0fc38bcc9d 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
@@ -286,16 +286,23 @@ public abstract class ClientAdapter implements ClientModel {
return cachedClient.getProtocolClaimMappings(); }
@Override
- public void addProtocolMappers(Set mappingIds) {
+ public void addProtocolMappers(Set mapperNames) {
getDelegateForUpdate();
- updatedClient.addProtocolMappers(mappingIds);
+ updatedClient.addProtocolMappers(mapperNames);
}
@Override
- public void removeProtocolMappers(Set mappingIds) {
+ public void removeProtocolMappers(Set mapperNames) {
getDelegateForUpdate();
- updatedClient.removeProtocolMappers(mappingIds);
+ updatedClient.removeProtocolMappers(mapperNames);
+
+ }
+
+ @Override
+ public void setProtocolMappers(Set mapperNames) {
+ getDelegateForUpdate();
+ updatedClient.setProtocolMappers(mapperNames);
}
}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
index 21d32cc037..debd784a91 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
@@ -919,6 +919,14 @@ public class RealmAdapter implements RealmModel {
return null;
}
+ @Override
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
+ for (ProtocolMapperModel mapping : cached.getClaimMappings()) {
+ if (mapping.getProtocol().equals(protocol) && mapping.getName().equals(name)) return mapping;
+ }
+ return null;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
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 c06cdecf57..d4616fd526 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
@@ -8,6 +8,7 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.jpa.entities.ClientEntity;
import org.keycloak.models.jpa.entities.IdentityProviderEntity;
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
+import org.keycloak.models.jpa.entities.RealmEntity;
import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.jpa.entities.ScopeMappingEntity;
@@ -17,6 +18,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -364,6 +366,7 @@ public abstract class ClientAdapter implements ClientModel {
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
+ mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setAppliedByDefault(entity.isAppliedByDefault());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
@@ -377,6 +380,18 @@ public abstract class ClientAdapter implements ClientModel {
return mappings;
}
+ protected ProtocolMapperEntity findProtocolMapperByName(String protocol, String name) {
+ TypedQuery query = em.createNamedQuery("getProtocolMapperByNameProtocol", ProtocolMapperEntity.class);
+ query.setParameter("name", name);
+ query.setParameter("protocol", protocol);
+ query.setParameter("realm", entity.getRealm());
+ List entities = query.getResultList();
+ if (entities.size() == 0) return null;
+ if (entities.size() > 1) throw new IllegalStateException("Should not be more than one protocol mapper with same name");
+ return query.getResultList().get(0);
+
+ }
+
@Override
public void addProtocolMappers(Set mappings) {
Collection entities = entity.getProtocolMappers();
@@ -384,9 +399,9 @@ public abstract class ClientAdapter implements ClientModel {
for (ProtocolMapperEntity rel : entities) {
already.add(rel.getId());
}
- for (String providerId : mappings) {
- if (!already.contains(providerId)) {
- ProtocolMapperEntity mapping = em.find(ProtocolMapperEntity.class, providerId);
+ for (String id : mappings) {
+ if (!already.contains(id)) {
+ ProtocolMapperEntity mapping = em.find(ProtocolMapperEntity.class, id);
if (mapping != null) {
entities.add(mapping);
}
@@ -407,6 +422,29 @@ public abstract class ClientAdapter implements ClientModel {
}
em.flush();
}
+ @Override
+ public void setProtocolMappers(Set mappings) {
+ Collection entities = entity.getProtocolMappers();
+ Iterator it = entities.iterator();
+ Set already = new HashSet();
+ while (it.hasNext()) {
+ ProtocolMapperEntity mapper = it.next();
+ if (mappings.contains(mapper.getId())) {
+ already.add(mapper.getId());
+ continue;
+ }
+ it.remove();
+ }
+ for (String id : mappings) {
+ if (!already.contains(id)) {
+ ProtocolMapperEntity mapping = em.find(ProtocolMapperEntity.class, id);
+ if (mapping != null) {
+ entities.add(mapping);
+ }
+ }
+ }
+ em.flush();
+ }
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
index 371d0488b4..3091cc9213 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
@@ -45,7 +45,7 @@ public class JpaRealmProvider implements RealmProvider {
em.persist(realm);
em.flush();
final RealmModel model = new RealmAdapter(session, em, realm);
- session.getKeycloakSessionFactory().publish(new RealmCreationEvent() {
+ session.getKeycloakSessionFactory().publish(new RealmModel.RealmCreationEvent() {
@Override
public RealmModel getCreatedRealm() {
return model;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 7578fd0ae0..00a3fbb79f 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -628,6 +628,17 @@ public class RealmAdapter implements RealmModel {
return this.addApplication(KeycloakModelUtils.generateId(), name);
}
+ public void addDefaultClientProtocolMappers(ClientModel client) {
+ Set adding = new HashSet();
+ for (ProtocolMapperEntity mapper : realm.getProtocolMappers()) {
+ if (mapper.isAppliedByDefault()) {
+ adding.add(mapper.getId());
+ }
+ }
+ client.setProtocolMappers(adding);
+
+ }
+
@Override
public ApplicationModel addApplication(String id, String name) {
ApplicationEntity applicationData = new ApplicationEntity();
@@ -639,6 +650,7 @@ public class RealmAdapter implements RealmModel {
em.persist(applicationData);
em.flush();
ApplicationModel resource = new ApplicationAdapter(this, em, session, applicationData);
+ addDefaultClientProtocolMappers(resource);
em.flush();
return resource;
}
@@ -702,7 +714,10 @@ public class RealmAdapter implements RealmModel {
data.setRealm(realm);
em.persist(data);
em.flush();
- return new OAuthClientAdapter(this, data, em);
+ OAuthClientModel model = new OAuthClientAdapter(this, data, em);
+ addDefaultClientProtocolMappers(model);
+ em.flush();
+ return model;
}
@Override
@@ -1259,7 +1274,7 @@ public class RealmAdapter implements RealmModel {
@Override
public Set getProtocolMappers() {
Set mappings = new HashSet();
- for (ProtocolMapperEntity entity : realm.getProtocolClaimMappings()) {
+ for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
@@ -1280,7 +1295,10 @@ public class RealmAdapter implements RealmModel {
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
- String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
+ if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
+ throw new RuntimeException("protocol mapper name must be unique per protocol");
+ }
+ String id = KeycloakModelUtils.generateId();
ProtocolMapperEntity entity = new ProtocolMapperEntity();
entity.setId(id);
entity.setName(model.getName());
@@ -1293,20 +1311,12 @@ public class RealmAdapter implements RealmModel {
entity.setConsentText(model.getConsentText());
em.persist(entity);
- ProtocolMapperModel mapping = new ProtocolMapperModel();
- mapping.setId(entity.getId());
- mapping.setName(model.getName());
- mapping.setProtocol(entity.getProtocol());
- mapping.setProtocolMapper(entity.getProtocolMapper());
- mapping.setAppliedByDefault(entity.isAppliedByDefault());
- mapping.setConfig(model.getConfig());
- mapping.setConsentRequired(entity.isConsentRequired());
- mapping.setConsentText(entity.getConsentText());
- return mapping;
+ realm.getProtocolMappers().add(entity);
+ return entityToModel(entity);
}
- protected ProtocolMapperEntity getProtocolMapper(String id) {
- for (ProtocolMapperEntity entity : realm.getProtocolClaimMappings()) {
+ protected ProtocolMapperEntity getProtocolMapperEntity(String id) {
+ for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
@@ -1315,11 +1325,21 @@ public class RealmAdapter implements RealmModel {
}
+ protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
+ for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
+ if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
+ return entity;
+ }
+ }
+ return null;
+
+ }
+
@Override
public void removeProtocolMapper(ProtocolMapperModel mapping) {
- ProtocolMapperEntity toDelete = getProtocolMapper(mapping.getId());
+ ProtocolMapperEntity toDelete = getProtocolMapperEntity(mapping.getId());
if (toDelete != null) {
- realm.getProtocolClaimMappings().remove(toDelete);
+ realm.getProtocolMappers().remove(toDelete);
em.remove(toDelete);
}
@@ -1327,7 +1347,7 @@ public class RealmAdapter implements RealmModel {
@Override
public void updateProtocolMapper(ProtocolMapperModel mapping) {
- ProtocolMapperEntity entity = getProtocolMapper(mapping.getId());
+ ProtocolMapperEntity entity = getProtocolMapperEntity(mapping.getId());
entity.setProtocolMapper(mapping.getProtocolMapper());
entity.setAppliedByDefault(mapping.isAppliedByDefault());
entity.setConsentRequired(mapping.isConsentRequired());
@@ -1344,12 +1364,24 @@ public class RealmAdapter implements RealmModel {
@Override
public ProtocolMapperModel getProtocolMapperById(String id) {
- ProtocolMapperEntity entity = getProtocolMapper(id);
+ ProtocolMapperEntity entity = getProtocolMapperEntity(id);
if (entity == null) return null;
+ return entityToModel(entity);
+ }
+
+ @Override
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
+ ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
+ if (entity == null) return null;
+ return entityToModel(entity);
+ }
+
+ protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
+ mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setAppliedByDefault(entity.isAppliedByDefault());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index ec8929e2a8..817fd8085c 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -77,7 +77,7 @@ public abstract class ClientEntity {
@JoinTable(name="CLIENT_ALLOWED_IDENTITY_PROVIDER", joinColumns = { @JoinColumn(name="CLIENT_ID")}, inverseJoinColumns = { @JoinColumn(name="INTERNAL_ID")})
Collection allowedIdentityProviders = new ArrayList();
- @OneToMany(cascade ={CascadeType.REMOVE})
+ @OneToMany(fetch = FetchType.LAZY)
@JoinTable(name="CLIENT_PROTOCOL_MAPPER", joinColumns = { @JoinColumn(name="CLIENT_ID")}, inverseJoinColumns = { @JoinColumn(name="MAPPING_ID")})
Collection protocolMappers = new ArrayList();
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
index bd8bbe2a0d..cfb79390e1 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
@@ -20,7 +20,7 @@ import java.util.Map;
*/
@Entity
@NamedQueries({
- @NamedQuery(name="deleteProtocolClaimMappersByRealm", query="delete from ProtocolMapperEntity attr where attr.realm = :realm")
+ @NamedQuery(name="getProtocolMapperByNameProtocol", query="select mapper from ProtocolMapperEntity mapper where mapper.protocol = :protocol and mapper.name = :name and mapper.realm = :realm")
})
@Table(name="PROTOCOL_MAPPER")
public class ProtocolMapperEntity {
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
index e9cdda1e78..2f24d06bf7 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
@@ -96,7 +96,7 @@ public class RealmEntity {
Collection claimTypes = new ArrayList();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
- Collection protocolClaimMappings = new ArrayList();
+ Collection protocolMappers = new ArrayList();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
Collection requiredCredentials = new ArrayList();
@@ -447,12 +447,12 @@ public class RealmEntity {
this.claimTypes = claimTypes;
}
- public Collection getProtocolClaimMappings() {
- return protocolClaimMappings;
+ public Collection getProtocolMappers() {
+ return protocolMappers;
}
- public void setProtocolClaimMappings(Collection protocolClaimMappings) {
- this.protocolClaimMappings = protocolClaimMappings;
+ public void setProtocolMappers(Collection protocolMappers) {
+ this.protocolMappers = protocolMappers;
}
}
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 1a6990dea0..8d87dc0b33 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
@@ -295,7 +295,7 @@ public abstract class ClientAdapter extends A
@Override
public Set getProtocolMappers() {
Set result = new HashSet();
- for (String id : getMongoEntityAsClient().getProtocolClaimMappings()) {
+ for (String id : getMongoEntityAsClient().getProtocolMappers()) {
ProtocolMapperModel model = getRealm().getProtocolMapperById(id);
if (model != null) result.add(model);
}
@@ -303,15 +303,22 @@ public abstract class ClientAdapter extends A
}
@Override
- public void addProtocolMappers(Set mappingIds) {
- getMongoEntityAsClient().getProtocolClaimMappings().addAll(mappingIds);
+ public void addProtocolMappers(Set mapperIds) {
+ getMongoEntityAsClient().getProtocolMappers().addAll(mapperIds);
updateMongoEntity();
}
@Override
- public void removeProtocolMappers(Set mappingIds) {
- getMongoEntityAsClient().getProtocolClaimMappings().removeAll(mappingIds);
+ public void removeProtocolMappers(Set mapperIds) {
+ getMongoEntityAsClient().getProtocolMappers().removeAll(mapperIds);
+ updateMongoEntity();
+ }
+
+ @Override
+ public void setProtocolMappers(Set mapperIds) {
+ getMongoEntityAsClient().getProtocolMappers().clear();
+ getMongoEntityAsClient().getProtocolMappers().addAll(mapperIds);
updateMongoEntity();
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
index 997025e888..61865d6e6e 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
@@ -52,7 +52,7 @@ public class MongoRealmProvider implements RealmProvider {
getMongoStore().insertEntity(newRealm, invocationContext);
final RealmModel model = new RealmAdapter(session, newRealm, invocationContext);
- session.getKeycloakSessionFactory().publish(new RealmCreationEvent() {
+ session.getKeycloakSessionFactory().publish(new RealmModel.RealmCreationEvent() {
@Override
public RealmModel getCreatedRealm() {
return model;
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 9b20f2a869..d48ae7d898 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -616,6 +616,14 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
return result;
}
+ public void addDefaultClientProtocolMappers(ClientModel client) {
+ Set adding = new HashSet();
+ for (ProtocolMapperEntity mapper : realm.getProtocolMappers()) {
+ if (mapper.isAppliedByDefault()) adding.add(mapper.getId());
+ }
+ client.setProtocolMappers(adding);
+
+ }
@Override
public ApplicationModel addApplication(String name) {
return this.addApplication(null, name);
@@ -630,7 +638,9 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
appData.setEnabled(true);
getMongoStore().insertEntity(appData, invocationContext);
- return new ApplicationAdapter(session, this, appData, invocationContext);
+ ApplicationModel model = new ApplicationAdapter(session, this, appData, invocationContext);
+ addDefaultClientProtocolMappers(model);
+ return model;
}
@Override
@@ -651,7 +661,9 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
oauthClient.setName(name);
getMongoStore().insertEntity(oauthClient, invocationContext);
- return new OAuthClientAdapter(session, this, oauthClient, invocationContext);
+ OAuthClientAdapter model = new OAuthClientAdapter(session, this, oauthClient, invocationContext);
+ addDefaultClientProtocolMappers(model);
+ return model;
}
@Override
@@ -808,9 +820,11 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
+ if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
+ throw new RuntimeException("protocol mapper name must be unique per protocol");
+ }
ProtocolMapperEntity entity = new ProtocolMapperEntity();
- if (model.getId() != null) entity.setId(model.getId());
- else entity.setId(KeycloakModelUtils.generateId());
+ entity.setId(KeycloakModelUtils.generateId());
entity.setProtocol(model.getProtocol());
entity.setName(model.getName());
entity.setAppliedByDefault(model.isAppliedByDefault());
@@ -820,15 +834,7 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
entity.setConsentText(model.getConsentText());
realm.getProtocolMappers().add(entity);
updateRealm();
- ProtocolMapperModel mapping = new ProtocolMapperModel();
- mapping.setId(entity.getId());
- mapping.setProtocol(model.getProtocol());
- mapping.setAppliedByDefault(model.isAppliedByDefault());
- mapping.setProtocolMapper(model.getProtocolMapper());
- mapping.setConfig(model.getConfig());
- mapping.setConsentText(model.getConsentText());
- mapping.setConsentRequired(model.isConsentRequired());
- return mapping;
+ return entityToModel(entity);
}
@Override
@@ -843,7 +849,7 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
}
- protected ProtocolMapperEntity getProtocolMapper(String id) {
+ protected ProtocolMapperEntity getProtocolMapperyEntityById(String id) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
if (entity.getId().equals(id)) {
return entity;
@@ -852,11 +858,20 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
return null;
}
+ protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
+ for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
+ if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
+ return entity;
+ }
+ }
+ return null;
+
+ }
@Override
public void updateProtocolMapper(ProtocolMapperModel mapping) {
- ProtocolMapperEntity entity = getProtocolMapper(mapping.getId());
+ ProtocolMapperEntity entity = getProtocolMapperyEntityById(mapping.getId());
entity.setAppliedByDefault(mapping.isAppliedByDefault());
entity.setProtocolMapper(mapping.getProtocolMapper());
entity.setConsentRequired(mapping.isConsentRequired());
@@ -873,8 +888,19 @@ public class RealmAdapter extends AbstractMongoAdapter impleme
@Override
public ProtocolMapperModel getProtocolMapperById(String id) {
- ProtocolMapperEntity entity = getProtocolMapper(id);
+ ProtocolMapperEntity entity = getProtocolMapperyEntityById(id);
if (entity == null) return null;
+ return entityToModel(entity);
+ }
+
+ @Override
+ public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
+ ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
+ if (entity == null) return null;
+ return entityToModel(entity);
+ }
+
+ protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
index d8ff2e4b38..4b60b6a2e5 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
@@ -4,11 +4,22 @@ import org.keycloak.Config;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.LoginProtocol;
import org.keycloak.protocol.LoginProtocolFactory;
+import org.keycloak.protocol.oidc.mappers.AttributeMapperHelper;
+import org.keycloak.protocol.oidc.mappers.OIDCAddressMapper;
+import org.keycloak.protocol.oidc.mappers.OIDCFullNameMapper;
+import org.keycloak.protocol.oidc.mappers.OIDCUserModelMapper;
+import org.keycloak.provider.ProviderEvent;
+import org.keycloak.provider.ProviderEventListener;
import org.keycloak.services.managers.AuthenticationManager;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
/**
* @author Bill Burke
* @version $Revision: 1 $
@@ -25,8 +36,107 @@ public class OIDCLoginProtocolFactory implements LoginProtocolFactory {
@Override
public void postInit(KeycloakSessionFactory factory) {
+ KeycloakSession session = factory.create();
+ session.getTransaction().begin();
+ try {
+ List realms = session.realms().getRealms();
+ for (RealmModel realm : realms) addMappers(realm);
+ session.getTransaction().commit();
+ } catch (Exception e) {
+ session.getTransaction().rollback();
+ } finally {
+ session.close();
+ }
+
+ factory.register(new ProviderEventListener() {
+ @Override
+ public void onEvent(ProviderEvent event) {
+ if (event instanceof RealmModel.RealmCreationEvent) {
+ RealmModel realm = ((RealmModel.RealmCreationEvent)event).getCreatedRealm();
+ addMappers(realm);
+ }
+ }
+ });
+
}
+
+ protected void addMappers(RealmModel realm) {
+ int counter = 0;
+ // the ids must never change!!!! So if you add more default mappers, then add to end with higher counter.
+ addClaimMapper(realm, "username", OIDCUserModelMapper.PROVIDER_ID,
+ OIDCUserModelMapper.USER_MODEL_PROPERTY, "username",
+ "preferred_username", "String",
+ true, "username",
+ true);
+ addClaimMapper(realm, "email", OIDCUserModelMapper.PROVIDER_ID,
+ OIDCUserModelMapper.USER_MODEL_PROPERTY, "email",
+ "email", "String",
+ true, "email",
+ true);
+ addClaimMapper(realm, "given name", OIDCUserModelMapper.PROVIDER_ID,
+ OIDCUserModelMapper.USER_MODEL_PROPERTY, "firstName",
+ "given_name", "String",
+ true, "given name",
+ true);
+ addClaimMapper(realm, "family name", OIDCUserModelMapper.PROVIDER_ID,
+ OIDCUserModelMapper.USER_MODEL_PROPERTY, "lastName",
+ "family_name", "String",
+ true, "family name",
+ true);
+ addClaimMapper(realm, "email verified", OIDCUserModelMapper.PROVIDER_ID,
+ OIDCUserModelMapper.USER_MODEL_PROPERTY, "emailVerified",
+ "email_verified", "boolean",
+ false, null,
+ false);
+
+ ProtocolMapperModel fullName = new ProtocolMapperModel();
+ if (realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "full name") == null) {
+ fullName.setName("full name");
+ fullName.setProtocolMapper(OIDCFullNameMapper.PROVIDER_ID);
+ fullName.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ fullName.setConsentRequired(true);
+ fullName.setConsentText("full name");
+ fullName.setAppliedByDefault(true);
+ realm.addProtocolMapper(fullName);
+ }
+
+ ProtocolMapperModel address = new ProtocolMapperModel();
+ if (realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "address") == null) {
+ address.setName("address");
+ address.setProtocolMapper(OIDCAddressMapper.PROVIDER_ID);
+ address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ address.setConsentRequired(true);
+ address.setConsentText("address");
+ address.setAppliedByDefault(false);
+ realm.addProtocolMapper(address);
+ }
+
+
+ }
+
+ protected void addClaimMapper(RealmModel realm, String name, String mapperRef,
+ String propertyName, String propertyNameValue,
+ String tokenClaimName, String claimType,
+ boolean consentRequired, String consentText,
+ boolean appliedByDefault) {
+ ProtocolMapperModel mapper = realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, name);
+ if (mapper != null) return;
+ mapper = new ProtocolMapperModel();
+ mapper.setName(name);
+ mapper.setProtocolMapper(mapperRef);
+ mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ mapper.setConsentRequired(consentRequired);
+ mapper.setConsentText(consentText);
+ mapper.setAppliedByDefault(appliedByDefault);
+ Map config = new HashMap();
+ config.put(propertyName, propertyNameValue);
+ config.put(AttributeMapperHelper.TOKEN_CLAIM_NAME, tokenClaimName);
+ config.put(AttributeMapperHelper.JSON_TYPE, claimType);
+ mapper.setConfig(config);
+ realm.addProtocolMapper(mapper);
+ }
+
@Override
public Object createProtocolEndpoint(RealmModel realm, EventBuilder event, AuthenticationManager authManager) {
return new OIDCLoginProtocolService(realm, event, authManager);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
index ae0ba0a457..5e4080976f 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
@@ -340,7 +340,7 @@ public class OIDCLoginProtocolService {
TokenManager.attachClientSession(userSession, clientSession);
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event)
- .generateAccessToken(scope, client, user, userSession, clientSession)
+ .generateAccessToken(session, scope, client, user, userSession, clientSession)
.generateRefreshToken()
.generateIDToken()
.build();
@@ -668,7 +668,7 @@ public class OIDCLoginProtocolService {
clientSession.setNote(AdapterConstants.APPLICATION_SESSION_HOST, adapterSessionHost);
}
- AccessToken token = tokenManager.createClientAccessToken(accessCode.getRequestedRoles(), realm, client, user, userSession, clientSession);
+ AccessToken token = tokenManager.createClientAccessToken(session, accessCode.getRequestedRoles(), realm, client, user, userSession, clientSession);
try {
tokenManager.verifyAccess(token, realm, client, user);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index 4c56df7df7..8e48aeb640 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -13,6 +13,7 @@ import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
@@ -20,6 +21,8 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.UserSessionProvider;
import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.protocol.ProtocolMapper;
+import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.UserClaimSet;
@@ -104,7 +107,7 @@ public class TokenManager {
AccessToken accessToken = initToken(realm, client, user, userSession, clientSession);
accessToken.setRealmAccess(refreshToken.getRealmAccess());
accessToken.setResourceAccess(refreshToken.getResourceAccess());
- accessToken = transformToken(accessToken, realm, client, user, userSession, clientSession);
+ accessToken = transformToken(session, accessToken, realm, client, user, userSession, clientSession);
userSession.setLastSessionRefresh(currentTime);
@@ -132,12 +135,12 @@ public class TokenManager {
return refreshToken;
}
- public AccessToken createClientAccessToken(Set requestedRoles, RealmModel realm, ClientModel client, UserModel user, UserSessionModel session, ClientSessionModel clientSession) {
- AccessToken token = initToken(realm, client, user, session, clientSession);
+ public AccessToken createClientAccessToken(KeycloakSession session, Set requestedRoles, RealmModel realm, ClientModel client, UserModel user, UserSessionModel userSession, ClientSessionModel clientSession) {
+ AccessToken token = initToken(realm, client, user, userSession, clientSession);
for (RoleModel role : requestedRoles) {
addComposites(token, role);
}
- token = transformToken(token, realm, client, user, session, clientSession);
+ token = transformToken(session, token, realm, client, user, userSession, clientSession);
return token;
}
@@ -232,36 +235,20 @@ public class TokenManager {
}
}
- public void initClaims(UserClaimSet claimSet, ClientModel model, UserModel user) {
- claimSet.setSubject(user.getId());
-
- if (ClaimMask.hasUsername(model.getAllowedClaimsMask())) {
- claimSet.setPreferredUsername(user.getUsername());
- }
- if (ClaimMask.hasEmail(model.getAllowedClaimsMask())) {
- claimSet.setEmail(user.getEmail());
- claimSet.setEmailVerified(user.isEmailVerified());
- }
- if (ClaimMask.hasName(model.getAllowedClaimsMask())) {
- claimSet.setFamilyName(user.getLastName());
- claimSet.setGivenName(user.getFirstName());
- StringBuilder fullName = new StringBuilder();
- if (user.getFirstName() != null) fullName.append(user.getFirstName()).append(" ");
- if (user.getLastName() != null) fullName.append(user.getLastName());
- claimSet.setName(fullName.toString());
- }
-
- Set mappings = model.getProtocolMappers();
+ public AccessToken transformToken(KeycloakSession session, AccessToken token, RealmModel realm, ClientModel client, UserModel user,
+ UserSessionModel userSession, ClientSessionModel clientSession) {
+ Set mappings = client.getProtocolMappers();
+ KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
for (ProtocolMapperModel mapping : mappings) {
if (!mapping.getProtocol().equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) continue;
- }
- }
+ ProtocolMapper mapper = (ProtocolMapper)sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
+ if (mapper == null || !(mapper instanceof OIDCAccessTokenMapper)) continue;
+ token = ((OIDCAccessTokenMapper)mapper).transformToken(token, mapping, session, userSession, clientSession);
- protected AccessToken transformToken(AccessToken token, RealmModel realm, ClientModel client, UserModel user,
- UserSessionModel session, ClientSessionModel clientSession) {
- UserClaimSet claimSet = token.getUserClaimSet();
- initClaims(claimSet, client, user);
+
+
+ }
return token;
}
@@ -350,9 +337,9 @@ public class TokenManager {
return this;
}
- public AccessTokenResponseBuilder generateAccessToken(String scopeParam, ClientModel client, UserModel user, UserSessionModel session, ClientSessionModel clientSession) {
+ public AccessTokenResponseBuilder generateAccessToken(KeycloakSession session, String scopeParam, ClientModel client, UserModel user, UserSessionModel userSession, ClientSessionModel clientSession) {
Set requestedRoles = getAccess(scopeParam, client, user);
- accessToken = createClientAccessToken(requestedRoles, realm, client, user, session, clientSession);
+ accessToken = createClientAccessToken(session, requestedRoles, realm, client, user, userSession, clientSession);
return this;
}
@@ -395,16 +382,11 @@ public class TokenManager {
idToken.getUserClaimSet().setEmail(accessToken.getUserClaimSet().getEmail());
idToken.getUserClaimSet().setEmailVerified(accessToken.getUserClaimSet().getEmailVerified());
idToken.getUserClaimSet().setLocale(accessToken.getUserClaimSet().getLocale());
- idToken.getUserClaimSet().setFormattedAddress(accessToken.getUserClaimSet().getFormattedAddress());
idToken.getUserClaimSet().setAddress(accessToken.getUserClaimSet().getAddress());
- idToken.getUserClaimSet().setStreetAddress(accessToken.getUserClaimSet().getStreetAddress());
- idToken.getUserClaimSet().setLocality(accessToken.getUserClaimSet().getLocality());
- idToken.getUserClaimSet().setRegion(accessToken.getUserClaimSet().getRegion());
- idToken.getUserClaimSet().setPostalCode(accessToken.getUserClaimSet().getPostalCode());
- idToken.getUserClaimSet().setCountry(accessToken.getUserClaimSet().getCountry());
idToken.getUserClaimSet().setPhoneNumber(accessToken.getUserClaimSet().getPhoneNumber());
idToken.getUserClaimSet().setPhoneNumberVerified(accessToken.getUserClaimSet().getPhoneNumberVerified());
idToken.getUserClaimSet().setZoneinfo(accessToken.getUserClaimSet().getZoneinfo());
+ idToken.setOtherClaims(accessToken.getOtherClaims());
return this;
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java b/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java
index 7a0e8a8951..0829d67f8b 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java
@@ -48,6 +48,8 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import java.util.HashMap;
+import java.util.Map;
/**
* @author pedroigor
@@ -130,9 +132,8 @@ public class UserInfoService {
UserSessionModel userSession = session.sessions().getUserSession(realmModel, accessToken.getSessionState());
ClientModel clientModel = realmModel.findClient(accessToken.getIssuedFor());
UserModel userModel = userSession.getUser();
- UserClaimSet userInfo = new UserClaimSet();
-
- this.tokenManager.initClaims(userInfo, clientModel, userModel);
+ AccessToken userInfo = new AccessToken();
+ this.tokenManager.transformToken(session, userInfo, realmModel, clientModel, userModel, userSession, null);
event
.detail(Details.USERNAME, userModel.getUsername())
@@ -141,7 +142,10 @@ public class UserInfoService {
.user(userModel)
.success();
- return Cors.add(request, Response.ok(userInfo)).auth().allowedOrigins(accessToken).build();
+ Map claims = new HashMap();
+ claims.putAll(userInfo.getOtherClaims());
+ claims.put("sub", userModel.getId());
+ return Cors.add(request, Response.ok(claims)).auth().allowedOrigins(accessToken).build();
} catch (Exception e) {
throw new UnauthorizedException("Could not retrieve user info.", e);
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AttributeMapperHelper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AttributeMapperHelper.java
new file mode 100755
index 0000000000..a4fe0fe0c8
--- /dev/null
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AttributeMapperHelper.java
@@ -0,0 +1,59 @@
+package org.keycloak.protocol.oidc.mappers;
+
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.representations.AccessToken;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class AttributeMapperHelper {
+ public static final String TOKEN_CLAIM_NAME = "Token Claim Name";
+ public static final String JSON_TYPE = "Claim JSON Type";
+
+ public static Object mapAttributeValue(ProtocolMapperModel mappingModel, Object attributeValue) {
+ if (attributeValue == null) return null;
+ String type = mappingModel.getConfig().get(JSON_TYPE);
+ if (type == null) return attributeValue;
+ if (type.equals("boolean")) {
+ if (attributeValue instanceof Boolean) return attributeValue;
+ if (attributeValue instanceof String) return Boolean.valueOf((String)attributeValue);
+ throw new RuntimeException("cannot map type for token claim");
+ } else if (type.equals("String")) {
+ if (attributeValue instanceof String) return attributeValue;
+ return attributeValue.toString();
+ } else if (type.equals("long")) {
+ if (attributeValue instanceof Long) return attributeValue;
+ if (attributeValue instanceof String) return Long.valueOf((String)attributeValue);
+ throw new RuntimeException("cannot map type for token claim");
+ } else if (type.equals("int")) {
+ if (attributeValue instanceof Integer) return attributeValue;
+ if (attributeValue instanceof String) return Integer.valueOf((String)attributeValue);
+ throw new RuntimeException("cannot map type for token claim");
+ }
+ return attributeValue;
+ }
+
+ public static void mapClaim(AccessToken token, ProtocolMapperModel mappingModel, Object attributeValue) {
+ if (attributeValue == null) return;
+ attributeValue = mapAttributeValue(mappingModel, attributeValue);
+ String protocolClaim = mappingModel.getConfig().get(TOKEN_CLAIM_NAME);
+ String[] split = protocolClaim.split("\\.");
+ Map jsonObject = token.getOtherClaims();
+ for (int i = 0; i < split.length; i++) {
+ if (i == split.length - 1) {
+ jsonObject.put(split[i], attributeValue);
+ } else {
+ Map nested = (Map)jsonObject.get(split[i]);
+ if (nested == null) {
+ nested = new HashMap();
+ jsonObject.put(split[i], nested);
+ jsonObject = nested;
+ }
+ }
+ }
+ }
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddressMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddressMapper.java
new file mode 100755
index 0000000000..ee7e8150e3
--- /dev/null
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddressMapper.java
@@ -0,0 +1,59 @@
+package org.keycloak.protocol.oidc.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.UserClaimSet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Set the 'name' claim to be first + last name.
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class OIDCAddressMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper {
+
+ private static final List configProperties = new ArrayList();
+
+ static {
+
+ }
+
+ public static final String PROVIDER_ID = "oidc-address-mapper";
+
+
+ public List getConfigProperties() {
+ return configProperties;
+ }
+
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Address Mapper";
+ }
+
+ @Override
+ public AccessToken transformToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session,
+ UserSessionModel userSession, ClientSessionModel clientSession) {
+ UserModel user = userSession.getUser();
+ UserClaimSet.AddressClaimSet addressSet = new UserClaimSet.AddressClaimSet();
+ addressSet.setStreetAddress(user.getAttribute("street"));
+ addressSet.setLocality(user.getAttribute("locality"));
+ addressSet.setRegion(user.getAttribute("region"));
+ addressSet.setPostalCode(user.getAttribute("postal_code"));
+ addressSet.setCountry(user.getAttribute("country"));
+ token.getOtherClaims().put("address", addressSet);
+ return token;
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCClientSessionNoteMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCClientSessionNoteMapper.java
index 3e38ed29e4..216c0fe972 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCClientSessionNoteMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCClientSessionNoteMapper.java
@@ -28,8 +28,8 @@ public class OIDCClientSessionNoteMapper extends AbstractOIDCProtocolMapper impl
property.setLabel(CLIENT_SESSION_NOTE);
property.setHelpText("Name of the note to map in the UserSessionModel");
configProperties.add(property);
- property.setName(OIDCUserAttributeMapper.TOKEN_CLAIM_NAME);
- property.setLabel(OIDCUserAttributeMapper.TOKEN_CLAIM_NAME);
+ property.setName(AttributeMapperHelper.TOKEN_CLAIM_NAME);
+ property.setLabel(AttributeMapperHelper.TOKEN_CLAIM_NAME);
property.setHelpText("Name of the claim to insert into the token. This can be a fully qualified name like 'address.street'. In this case, a nested json object will be created.");
configProperties.add(property);
@@ -53,7 +53,7 @@ public class OIDCClientSessionNoteMapper extends AbstractOIDCProtocolMapper impl
UserSessionModel userSession, ClientSessionModel clientSession) {
String note = mappingModel.getConfig().get(CLIENT_SESSION_NOTE);
String noteValue = clientSession.getNote(note);
- OIDCUserAttributeMapper.mapClaim(token, mappingModel, noteValue);
+ AttributeMapperHelper.mapClaim(token, mappingModel, noteValue);
return token;
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCFullNameMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCFullNameMapper.java
new file mode 100755
index 0000000000..b77783a647
--- /dev/null
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCFullNameMapper.java
@@ -0,0 +1,54 @@
+package org.keycloak.protocol.oidc.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.representations.AccessToken;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Set the 'name' claim to be first + last name.
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class OIDCFullNameMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper {
+
+ private static final List configProperties = new ArrayList();
+
+ static {
+
+ }
+
+ public static final String PROVIDER_ID = "oidc-full-name-mapper";
+
+
+ public List getConfigProperties() {
+ return configProperties;
+ }
+
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Full name Mapper";
+ }
+
+ @Override
+ public AccessToken transformToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session,
+ UserSessionModel userSession, ClientSessionModel clientSession) {
+ UserModel user = userSession.getUser();
+ String first = user.getFirstName() == null ? "" : user.getFirstName() + " ";
+ String last = user.getLastName() == null ? "" : user.getLastName();
+ token.getOtherClaims().put("name", first + last);
+ return token;
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java
index 1c687be3b5..c5435588b9 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserAttributeMapper.java
@@ -7,11 +7,8 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.representations.AccessToken;
-import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* Mappings UserModel.attribute to an ID Token claim. Token claim name can be a full qualified nested object name,
@@ -23,7 +20,6 @@ import java.util.Map;
*/
public class OIDCUserAttributeMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper {
- public static final String TOKEN_CLAIM_NAME = "Token Claim Name";
private static final List configProperties = new ArrayList();
public static final String USER_MODEL_ATTRIBUTE_NAME = "UserModel Attribute Name";
@@ -34,13 +30,15 @@ public class OIDCUserAttributeMapper extends AbstractOIDCProtocolMapper implemen
property.setLabel(USER_MODEL_ATTRIBUTE_NAME);
property.setHelpText("Name of stored user attribute which is the name of an attribute within the UserModel.attribute map.");
configProperties.add(property);
- property.setName(TOKEN_CLAIM_NAME);
- property.setLabel(TOKEN_CLAIM_NAME);
+ property.setName(AttributeMapperHelper.TOKEN_CLAIM_NAME);
+ property.setLabel(AttributeMapperHelper.TOKEN_CLAIM_NAME);
property.setHelpText("Name of the claim to insert into the token. This can be a fully qualified name like 'address.street'. In this case, a nested json object will be created.");
configProperties.add(property);
}
+ public static final String PROVIDER_ID = "oidc-usermodel-attribute-mapper";
+
public List getConfigProperties() {
return configProperties;
@@ -48,7 +46,7 @@ public class OIDCUserAttributeMapper extends AbstractOIDCProtocolMapper implemen
@Override
public String getId() {
- return "oidc-usermodel-attribute-mapper";
+ return PROVIDER_ID;
}
@Override
@@ -63,26 +61,8 @@ public class OIDCUserAttributeMapper extends AbstractOIDCProtocolMapper implemen
String attributeName = mappingModel.getConfig().get(USER_MODEL_ATTRIBUTE_NAME);
String attributeValue = user.getAttribute(attributeName);
if (attributeValue == null) return token;
- mapClaim(token, mappingModel, attributeValue);
+ AttributeMapperHelper.mapClaim(token, mappingModel, attributeValue);
return token;
}
- protected static void mapClaim(AccessToken token, ProtocolMapperModel mappingModel, String attributeValue) {
- if (attributeValue == null) return;
- String protocolClaim = mappingModel.getConfig().get(TOKEN_CLAIM_NAME);
- String[] split = protocolClaim.split(".");
- Map jsonObject = token.getOtherClaims();
- for (int i = 0; i < split.length; i++) {
- if (i == split.length - 1) {
- jsonObject.put(split[i], attributeValue);
- } else {
- Map nested = (Map)jsonObject.get(split[i]);
- if (nested == null) {
- nested = new HashMap();
- jsonObject.put(split[i], nested);
- jsonObject = nested;
- }
- }
- }
- }
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java
index 4af3178680..6c30080321 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserModelMapper.java
@@ -9,9 +9,7 @@ import org.keycloak.representations.AccessToken;
import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* Mappings UserModel property (the property name of a getter method) to an ID Token claim. Token claim name can be a full qualified nested object name,
@@ -32,20 +30,22 @@ public class OIDCUserModelMapper extends AbstractOIDCProtocolMapper implements O
property.setLabel(USER_MODEL_PROPERTY);
property.setHelpText("Name of the property method in the UserModel interface. For example, a value of 'email' would reference the UserModel.getEmail() method.");
configProperties.add(property);
- property.setName(OIDCUserAttributeMapper.TOKEN_CLAIM_NAME);
- property.setLabel(OIDCUserAttributeMapper.TOKEN_CLAIM_NAME);
+ property.setName(AttributeMapperHelper.TOKEN_CLAIM_NAME);
+ property.setLabel(AttributeMapperHelper.TOKEN_CLAIM_NAME);
property.setHelpText("Name of the claim to insert into the token. This can be a fully qualified name like 'address.street'. In this case, a nested json object will be created.");
configProperties.add(property);
}
+ public static final String PROVIDER_ID = "oidc-usermodel-property-mapper";
+
public List getConfigProperties() {
return configProperties;
}
@Override
public String getId() {
- return "oidc-usermodel-property-mapper";
+ return PROVIDER_ID;
}
@Override
@@ -59,7 +59,7 @@ public class OIDCUserModelMapper extends AbstractOIDCProtocolMapper implements O
UserModel user = userSession.getUser();
String propertyName = mappingModel.getConfig().get(USER_MODEL_PROPERTY);
String propertyValue = getUserModelValue(user,propertyName);
- OIDCUserAttributeMapper.mapClaim(token, mappingModel, propertyValue);
+ AttributeMapperHelper.mapClaim(token, mappingModel, propertyValue);
return token;
}
@@ -73,6 +73,14 @@ public class OIDCUserModelMapper extends AbstractOIDCProtocolMapper implements O
if (val != null) return val.toString();
} catch (Exception ignore) {
+ }
+ methodName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
+ try {
+ Method method = UserModel.class.getMethod(methodName);
+ Object val = method.invoke(user);
+ if (val != null) return val.toString();
+ } catch (Exception ignore) {
+
}
return null;
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserSessionNoteMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserSessionNoteMapper.java
index 0069d5a25d..e430f4d528 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserSessionNoteMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCUserSessionNoteMapper.java
@@ -28,8 +28,8 @@ public class OIDCUserSessionNoteMapper extends AbstractOIDCProtocolMapper implem
property.setLabel("UserSession Note");
property.setHelpText("Name of the note to map in the UserSessionModel");
configProperties.add(property);
- property.setName(OIDCUserAttributeMapper.TOKEN_CLAIM_NAME);
- property.setLabel(OIDCUserAttributeMapper.TOKEN_CLAIM_NAME);
+ property.setName(AttributeMapperHelper.TOKEN_CLAIM_NAME);
+ property.setLabel(AttributeMapperHelper.TOKEN_CLAIM_NAME);
property.setHelpText("Name of the claim to insert into the token. This can be a fully qualified name like 'address.street'. In this case, a nested json object will be created.");
configProperties.add(property);
@@ -54,7 +54,7 @@ public class OIDCUserSessionNoteMapper extends AbstractOIDCProtocolMapper implem
UserSessionModel userSession, ClientSessionModel clientSession) {
String note = mappingModel.getConfig().get(USER_SESSION_NOTE);
String noteValue = userSession.getNote(note);
- OIDCUserAttributeMapper.mapClaim(token, mappingModel, noteValue);
+ AttributeMapperHelper.mapClaim(token, mappingModel, noteValue);
return token;
}
diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java
index 361eb87aec..dc03c490b4 100755
--- a/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java
+++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakSessionFactory.java
@@ -87,6 +87,11 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory {
}
}
}
+ for ( Map factories : factoriesMap.values()) {
+ for (ProviderFactory factory : factories.values()) {
+ factory.postInit(this);
+ }
+ }
}
public KeycloakSession create() {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index 5e5a24211c..583d886633 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -4,6 +4,7 @@ import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
@@ -87,6 +88,14 @@ public class ApplicationResource {
return new ClaimResource(application, auth);
}
+ @Path("protocol-mappers")
+ public ClientProtocolMappersResource getProtocolMappers() {
+ ClientProtocolMappersResource mappers = new ClientProtocolMappersResource(realm, auth, application);
+ ResteasyProviderFactory.getInstance().injectProperties(mappers);
+ //resourceContext.initResource(mappers);
+ return mappers;
+ }
+
/**
* Update the application.
* @param rep
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientProtocolMappersResource.java
new file mode 100755
index 0000000000..b4d9456945
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientProtocolMappersResource.java
@@ -0,0 +1,134 @@
+package org.keycloak.services.resources.admin;
+
+import org.jboss.logging.Logger;
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Base resource for managing users
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class ClientProtocolMappersResource {
+ protected static final Logger logger = Logger.getLogger(ClientProtocolMappersResource.class);
+ protected ClientModel client;
+ protected RealmModel realm;
+ protected RealmAuth auth;
+
+ @Context
+ protected UriInfo uriInfo;
+
+ @Context
+ protected KeycloakSession session;
+
+ public ClientProtocolMappersResource(RealmModel realm, RealmAuth auth, ClientModel client) {
+ this.auth = auth;
+ this.realm = realm;
+ this.client = client;
+
+ auth.init(RealmAuth.Resource.USER);
+ }
+
+ /**
+ * Map of mappers by name for a specific protocol attached to the client
+ *
+ * @param protocol
+ * @return
+ */
+ @GET
+ @NoCache
+ @Path("protocol/{protocol}")
+ @Produces("application/json")
+ public Map getMappersPerProtocol(@PathParam("protocol") String protocol) {
+ auth.requireView();
+ Map mappers = new HashMap();
+ for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
+ mappers.put(mapper.getName(), ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+ /**
+ * Add mappers to client.
+ *
+ * @param mapperIds List of mapper ids
+ */
+ @Path("models/add")
+ @PUT
+ @NoCache
+ @Consumes("application/json")
+ public void addMappers(Set mapperIds) {
+ auth.requireManage();
+ client.addProtocolMappers(mapperIds);
+ }
+
+ /**
+ * replace sets of client mappers.
+ *
+ * @param mapperIds List of mapper ids
+ */
+ @Path("models/set")
+ @PUT
+ @NoCache
+ @Consumes("application/json")
+ public void setMappers(Set mapperIds) {
+ auth.requireManage();
+ client.setProtocolMappers(mapperIds);
+ }
+
+ /**
+ * remove client mappers.
+ *
+ * @param mapperIds List of mapper ids
+ */
+ @Path("models/remove")
+ @PUT
+ @NoCache
+ @Consumes("application/json")
+ public void removeMappers(Set mapperIds) {
+ auth.requireManage();
+ client.removeProtocolMappers(mapperIds);
+ }
+
+ @GET
+ @NoCache
+ @Path("models")
+ @Produces("application/json")
+ public List getMappersPerProtocol() {
+ auth.requireView();
+ List mappers = new LinkedList();
+ for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
+ mappers.add(ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index 1bdf4109f2..e5768e6f0b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -3,6 +3,7 @@ package org.keycloak.services.resources.admin;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.OAuthClientModel;
@@ -73,6 +74,19 @@ public class OAuthClientResource {
return new ClaimResource(oauthClient, auth);
}
+ /**
+ * interface for updating attached ProtocolMappers
+ *
+ * @return
+ */
+ @Path("protocol-mappers")
+ public ClientProtocolMappersResource getProtocolMappers() {
+ ClientProtocolMappersResource mappers = new ClientProtocolMappersResource(realm, auth, oauthClient);
+ ResteasyProviderFactory.getInstance().injectProperties(mappers);
+ //resourceContext.initResource(mappers);
+ return mappers;
+ }
+
/**
*
* @param attributePrefix
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
new file mode 100755
index 0000000000..2a7c82a6a1
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
@@ -0,0 +1,150 @@
+package org.keycloak.services.resources.admin;
+
+import org.jboss.logging.Logger;
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.models.KerberosConstants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserFederationProvider;
+import org.keycloak.models.UserFederationProviderFactory;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
+import org.keycloak.representations.idm.UserFederationProviderRepresentation;
+import org.keycloak.services.managers.UsersSyncManager;
+import org.keycloak.timer.TimerProvider;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base resource for managing users
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class ProtocolMappersResource {
+ protected static final Logger logger = Logger.getLogger(ProtocolMappersResource.class);
+
+ protected RealmModel realm;
+
+ protected RealmAuth auth;
+
+ @Context
+ protected UriInfo uriInfo;
+
+ @Context
+ protected KeycloakSession session;
+
+ public ProtocolMappersResource(RealmModel realm, RealmAuth auth) {
+ this.auth = auth;
+ this.realm = realm;
+
+ auth.init(RealmAuth.Resource.USER);
+ }
+
+ /**
+ * Map of mappers by name for a specific protocol
+ *
+ * @param protocol
+ * @return
+ */
+ @GET
+ @NoCache
+ @Path("protocol/{protocol}")
+ @Produces("application/json")
+ public Map getMappersPerProtocol(@PathParam("protocol") String protocol) {
+ auth.requireView();
+ Map mappers = new HashMap();
+ for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
+ mappers.put(mapper.getName(), ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+ /**
+ * createa mapper
+ *
+ * @param rep
+ */
+ @Path("models")
+ @POST
+ @NoCache
+ @Consumes("application/json")
+ public Response createMapper(ProtocolMapperRepresentation rep) {
+ auth.requireManage();
+ ProtocolMapperModel model = RepresentationToModel.toModel(rep);
+ realm.addProtocolMapper(model);
+ return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
+ }
+
+ @GET
+ @NoCache
+ @Path("models")
+ @Produces("application/json")
+ public List getMappersPerProtocol() {
+ auth.requireView();
+ List mappers = new LinkedList();
+ for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
+ mappers.add(ModelToRepresentation.toRepresentation(mapper));
+ }
+ return mappers;
+ }
+
+ @GET
+ @NoCache
+ @Path("models/{id}")
+ @Produces("application/json")
+ public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) {
+ auth.requireView();
+ ProtocolMapperModel model = realm.getProtocolMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ return ModelToRepresentation.toRepresentation(model);
+ }
+
+ @PUT
+ @NoCache
+ @Path("models/{id}")
+ @Consumes("application/json")
+ public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) {
+ auth.requireManage();
+ ProtocolMapperModel model = realm.getProtocolMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ model = RepresentationToModel.toModel(rep);
+ realm.updateProtocolMapper(model);
+ }
+
+ @DELETE
+ @NoCache
+ @Path("models/{id}")
+ public void delete(@PathParam("id") String id) {
+ auth.requireManage();
+ ProtocolMapperModel model = realm.getProtocolMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ realm.removeProtocolMapper(model);
+ }
+
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 3e5c2b0bd8..592fa6f098 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -273,6 +273,19 @@ public class RealmAdminResource {
return new ResourceAdminManager().pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
}
+ /**
+ * Protocol mappers
+ *
+ */
+ @Path("protocol-mappers")
+ @POST
+ public ProtocolMappersResource protocolMappers() {
+ ProtocolMappersResource mappers = new ProtocolMappersResource(realm, auth);
+ ResteasyProviderFactory.getInstance().injectProperties(mappers);
+ //resourceContext.initResource(mappers);
+ return mappers;
+ }
+
/**
* Removes all user sessions. Any application that has an admin url will also be told to invalidate any sessions
* they have.
@@ -281,7 +294,6 @@ public class RealmAdminResource {
@Path("logout-all")
@POST
public GlobalRequestResult logoutAll() {
- auth.requireManage();
session.sessions().removeUserSessions(realm);
return new ResourceAdminManager().logoutAll(uriInfo.getRequestUri(), realm);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
index 6952e88472..f1d3e355e0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
@@ -120,7 +120,6 @@ public class ServerInfoAdminResource {
}
}
-
private void setProtocols(ServerInfoRepresentation info) {
info.protocols = new LinkedList();
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class)) {
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper b/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
index 0f9da65a17..1815b887d4 100755
--- a/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
+++ b/services/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
@@ -1 +1,8 @@
-org.keycloak.protocol.oidc.mappers.OIDCUserAttributeMapper
\ No newline at end of file
+org.keycloak.protocol.oidc.mappers.OIDCUserAttributeMapper
+org.keycloak.protocol.oidc.mappers.OIDCClientSessionNoteMapper
+org.keycloak.protocol.oidc.mappers.OIDCFullNameMapper
+org.keycloak.protocol.oidc.mappers.OIDCUserModelMapper
+org.keycloak.protocol.oidc.mappers.OIDCUserSessionNoteMapper
+org.keycloak.protocol.oidc.mappers.OIDCAddressMapper
+
+
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index 7cea20de62..30eeb3e59b 100755
--- a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1,2 +1,3 @@
org.keycloak.protocol.LoginProtocolSpi
+org.keycloak.protocol.ProtocolMapperSpi
org.keycloak.exportimport.ApplicationImportSpi
\ No newline at end of file
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index 08f57757af..cfe16a8e76 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -139,7 +139,7 @@ public class AdapterTestStrategy extends ExternalResource {
TokenManager tm = new TokenManager();
UserModel admin = session.users().getUserByUsername("admin", adminRealm);
UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false);
- AccessToken token = tm.createClientAccessToken(TokenManager.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+ AccessToken token = tm.createClientAccessToken(session, TokenManager.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
return tm.encodeToken(adminRealm, token);
} finally {
keycloakRule.stopSession(session, true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
index 0ebb8fc201..cce65bd49e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
@@ -87,7 +87,7 @@ public class RelativeUriAdapterTest {
TokenManager tm = new TokenManager();
UserModel admin = session.users().getUserByUsername("admin", adminRealm);
UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "user", null, "form", false);
- AccessToken token = tm.createClientAccessToken(tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+ AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
adminToken = tm.encodeToken(adminRealm, token);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
index 0d6c30fd3f..68e3f13540 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
@@ -79,7 +79,7 @@ public class AdminAPITest {
TokenManager tm = new TokenManager();
UserModel admin = session.users().getUserByUsername("admin", adminRealm);
UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false);
- AccessToken token = tm.createClientAccessToken(tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+ AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
return tm.encodeToken(adminRealm, token);
} finally {
keycloakRule.stopSession(session, true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
index 82c0ec9289..db33eb1340 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
@@ -247,7 +247,7 @@ public class SamlBindingTest {
TokenManager tm = new TokenManager();
UserModel admin = session.users().getUserByUsername("admin", adminRealm);
UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false);
- AccessToken token = tm.createClientAccessToken(tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+ AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
return tm.encodeToken(adminRealm, token);
} finally {
keycloakRule.stopSession(session, true);