keycloak-memoizeit
Changes
broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProviderFactory.java 3(+0 -3)
core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperRepresentation.java 57(+57 -0)
core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperTypeRepresentation.java 56(+56 -0)
core/src/main/java/org/keycloak/representations/idm/ProtocolMapperTypeRepresentation.java 54(+3 -51)
services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java 109(+109 -0)
Details
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java b/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java
index d65081d..a231346 100755
--- a/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/AbstractIdentityProvider.java
@@ -20,6 +20,7 @@ package org.keycloak.broker.provider;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
@@ -68,12 +69,12 @@ public abstract class AbstractIdentityProvider<C extends IdentityProviderModel>
}
@Override
- public void importNewUser(UserModel user, BrokeredIdentityContext context) {
+ public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context) {
}
@Override
- public void updateBrokeredUser(UserModel user, BrokeredIdentityContext context) {
+ public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context) {
}
}
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
index 0517b3a..01d5455 100755
--- a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
@@ -21,6 +21,7 @@ import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
@@ -28,7 +29,6 @@ import org.keycloak.provider.Provider;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
-import java.util.Map;
/**
* @author Pedro Igor
@@ -46,15 +46,9 @@ public interface IdentityProvider<C extends IdentityProviderModel> extends Provi
public Response authenticated(BrokeredIdentityContext context);
}
- /**
- *
- * @param userSession
- * @param clientSession
- * @param context
- */
void attachUserSession(UserSessionModel userSession, ClientSessionModel clientSession, BrokeredIdentityContext context);
- void importNewUser(UserModel user, BrokeredIdentityContext context);
- void updateBrokeredUser(UserModel user, BrokeredIdentityContext context);
+ void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context);
+ void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, BrokeredIdentityContext context);
/**
* JAXRS callback endpoint for when the remote IDP wants to callback to keycloak.
@@ -67,12 +61,6 @@ public interface IdentityProvider<C extends IdentityProviderModel> extends Provi
* <p>Initiates the authentication process by sending an authentication request to an identity provider. This method is called
* only once during the authentication.</p>
*
- * <p>Depending on how the authentication is performed, this method may redirect the user to the identity provider for authentication.
- * In this case, the response would contain a {@link javax.ws.rs.core.Response} that will be used to redirect the user.</p>
- *
- * <p>However, if the authentication flow does not require a redirect to the identity provider (eg.: simple challenge/response mechanism), this method may return a response containing
- * a {@link FederatedIdentity} representing the identity information for an user. In this case, the authentication flow stops.</p>
- *
* @param request The initial authentication request. Contains all the contextual information in order to build an authentication request to the
* identity provider.
* @return
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapper.java b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapper.java
new file mode 100755
index 0000000..990c6de
--- /dev/null
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapper.java
@@ -0,0 +1,24 @@
+package org.keycloak.broker.provider;
+
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.provider.ConfiguredProvider;
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface IdentityProviderMapper extends Provider, ProviderFactory<IdentityProviderMapper>,ConfiguredProvider {
+ String[] getCompatibleProviders();
+ String getDisplayCategory();
+ String getDisplayType();
+
+ void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context);
+ void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context);
+
+
+}
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapperSpi.java b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapperSpi.java
new file mode 100755
index 0000000..e660700
--- /dev/null
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapperSpi.java
@@ -0,0 +1,27 @@
+package org.keycloak.broker.provider;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class IdentityProviderMapperSpi implements Spi {
+
+ @Override
+ public String getName() {
+ return "identity-provider-mapper";
+ }
+
+ @Override
+ public Class<? extends Provider> getProviderClass() {
+ return IdentityProviderMapper.class;
+ }
+
+ @Override
+ public Class<? extends ProviderFactory> getProviderFactoryClass() {
+ return IdentityProviderMapper.class;
+ }
+
+}
diff --git a/broker/core/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/broker/core/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index d4ef41b..fa44621 100755
--- a/broker/core/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/broker/core/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1 +1,2 @@
-org.keycloak.broker.provider.IdentityProviderSpi
\ No newline at end of file
+org.keycloak.broker.provider.IdentityProviderSpi
+org.keycloak.broker.provider.IdentityProviderMapperSpi
\ No newline at end of file
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
index 0581eb1..60b1f4a 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
@@ -26,17 +26,13 @@ import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.AbstractIdentityProvider;
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
-import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.flows.Flows;
@@ -49,8 +45,6 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java
index ff89a89..14626c5 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProvider.java
@@ -95,4 +95,6 @@ public class KeycloakOIDCIdentityProvider extends OIDCIdentityProvider {
}
+
+
}
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProviderFactory.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProviderFactory.java
index 6a47135..b59a427 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProviderFactory.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProviderFactory.java
@@ -19,10 +19,7 @@ package org.keycloak.broker.oidc;
import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
import org.keycloak.models.IdentityProviderModel;
-import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
-import org.keycloak.util.JsonSerialization;
-import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
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 19a0f9d..eb73c0a 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
@@ -19,11 +19,9 @@ package org.keycloak.broker.oidc;
import org.codehaus.jackson.JsonNode;
import org.jboss.logging.Logger;
-import org.keycloak.RSATokenVerifier;
import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
@@ -36,6 +34,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.IDToken;
+import org.keycloak.representations.JsonWebToken;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.IdentityBrokerService;
@@ -53,7 +52,6 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.security.PublicKey;
-import java.util.Map;
/**
* @author Pedro Igor
@@ -178,14 +176,14 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
- IDToken idToken = validateIdToken(key, encodedIdToken);
+ JsonWebToken idToken = validateIdToken(key, encodedIdToken);
try {
String id = idToken.getSubject();
BrokeredIdentityContext identity = new BrokeredIdentityContext(id);
- String name = idToken.getName();
- String preferredUsername = idToken.getPreferredUsername();
- String email = idToken.getEmail();
+ String name = (String)idToken.getOtherClaims().get(IDToken.NAME);
+ String preferredUsername = (String)idToken.getOtherClaims().get(IDToken.PREFERRED_USERNAME);
+ String email = (String)idToken.getOtherClaims().get(IDToken.EMAIL);
if (getConfig().getUserInfoUrl() != null && (id == null || name == null || preferredUsername == null || email == null) ) {
JsonNode userInfo = SimpleHttp.doGet(getConfig().getUserInfoUrl())
@@ -239,7 +237,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
return accessToken;
}
- private IDToken validateIdToken(PublicKey key, String encodedToken) {
+ private JsonWebToken validateIdToken(PublicKey key, String encodedToken) {
if (encodedToken == null) {
throw new IdentityBrokerException("No id_token from server.");
}
@@ -249,7 +247,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
if (!verify(jws, key)) {
throw new IdentityBrokerException("IDToken signature validation failed");
}
- IDToken idToken = jws.readJsonContent(IDToken.class);
+ JsonWebToken idToken = jws.readJsonContent(JsonWebToken.class);
String aud = idToken.getAudience();
String iss = idToken.getIssuer();
@@ -285,16 +283,6 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
}
@Override
- public void importNewUser(UserModel user, BrokeredIdentityContext context) {
-
- }
-
- @Override
- public void updateBrokeredUser(UserModel user, BrokeredIdentityContext context) {
-
- }
-
- @Override
protected String getDefaultScopes() {
return "openid";
}
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java
index 4610140..7c3335e 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java
@@ -17,7 +17,6 @@
*/
package org.keycloak.broker.oidc;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
import org.keycloak.jose.jwk.JWK;
@@ -27,7 +26,6 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.oidc.representations.JSONWebKeySet;
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
import org.keycloak.util.JsonSerialization;
-import org.keycloak.util.PemUtils;
import java.io.IOException;
import java.io.InputStream;
diff --git a/broker/oidc/src/test/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProviderTest.java b/broker/oidc/src/test/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProviderTest.java
index 32e132d..0dcde56 100755
--- a/broker/oidc/src/test/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProviderTest.java
+++ b/broker/oidc/src/test/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProviderTest.java
@@ -5,18 +5,17 @@
*/
package org.keycloak.broker.oidc;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
import org.codehaus.jackson.JsonNode;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.models.IdentityProviderModel;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Unit test for {@link AbstractOAuth2IdentityProvider}
*
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 efee926..b13ff09 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
@@ -4,9 +4,17 @@ import org.jboss.logging.Logger;
import org.keycloak.ClientConnection;
import org.keycloak.VerificationException;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
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.AuthnStatementType;
+import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
+import org.keycloak.dom.saml.v2.assertion.SubjectType;
+import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
+import org.keycloak.dom.saml.v2.protocol.RequestAbstractType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
@@ -18,9 +26,6 @@ import org.keycloak.protocol.saml.SAML2LogoutResponseBuilder;
import org.keycloak.protocol.saml.SAMLRequestParser;
import org.keycloak.protocol.saml.SamlProtocol;
import org.keycloak.protocol.saml.SamlProtocolUtils;
-import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.services.messages.Messages;
-import org.keycloak.services.resources.flows.Flows;
import org.keycloak.saml.common.constants.GeneralConstants;
import org.keycloak.saml.common.constants.JBossSAMLConstants;
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
@@ -34,15 +39,9 @@ import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
import org.keycloak.saml.processing.core.util.XMLSignatureUtil;
-import org.keycloak.dom.saml.v2.assertion.AssertionType;
-import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
-import org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType;
-import org.keycloak.dom.saml.v2.assertion.NameIDType;
-import org.keycloak.dom.saml.v2.assertion.SubjectType;
-import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
-import org.keycloak.dom.saml.v2.protocol.RequestAbstractType;
-import org.keycloak.dom.saml.v2.protocol.ResponseType;
-import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.messages.Messages;
+import org.keycloak.services.resources.flows.Flows;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -63,9 +62,7 @@ import java.io.IOException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
index aaec932..f88c45d 100755
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
@@ -137,16 +137,6 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
}
@Override
- public void importNewUser(UserModel user, BrokeredIdentityContext context) {
-
- }
-
- @Override
- public void updateBrokeredUser(UserModel user, BrokeredIdentityContext context) {
-
- }
-
- @Override
public Response retrieveToken(FederatedIdentityModel identity) {
return Response.ok(identity.getToken()).build();
}
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java
index 0abf926..98ad908 100755
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java
@@ -18,17 +18,17 @@
package org.keycloak.broker.saml;
import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
-import org.keycloak.models.IdentityProviderModel;
-import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
-import org.keycloak.saml.common.exceptions.ParsingException;
-import org.keycloak.saml.common.util.DocumentUtil;
-import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
import org.keycloak.dom.saml.v2.metadata.EndpointType;
import org.keycloak.dom.saml.v2.metadata.EntitiesDescriptorType;
import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
import org.keycloak.dom.saml.v2.metadata.IDPSSODescriptorType;
import org.keycloak.dom.saml.v2.metadata.KeyDescriptorType;
import org.keycloak.dom.saml.v2.metadata.KeyTypes;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
diff --git a/core/src/main/java/org/keycloak/representations/AddressClaimSet.java b/core/src/main/java/org/keycloak/representations/AddressClaimSet.java
index 4b47b8f..3805f6e 100755
--- a/core/src/main/java/org/keycloak/representations/AddressClaimSet.java
+++ b/core/src/main/java/org/keycloak/representations/AddressClaimSet.java
@@ -7,22 +7,29 @@ import org.codehaus.jackson.annotate.JsonProperty;
* @version $Revision: 1 $
*/
public class AddressClaimSet {
- @JsonProperty("formatted")
+ public static final String FORMATTED = "formatted";
+ public static final String STREET_ADDRESS = "street_address";
+ public static final String LOCALITY = "locality";
+ public static final String REGION = "region";
+ public static final String POSTAL_CODE = "postal_code";
+ public static final String COUNTRY = "country";
+
+ @JsonProperty(FORMATTED)
protected String formattedAddress;
- @JsonProperty("street_address")
+ @JsonProperty(STREET_ADDRESS)
protected String streetAddress;
- @JsonProperty("locality")
+ @JsonProperty(LOCALITY)
protected String locality;
- @JsonProperty("region")
+ @JsonProperty(REGION)
protected String region;
- @JsonProperty("postal_code")
+ @JsonProperty(POSTAL_CODE)
protected String postalCode;
- @JsonProperty("country")
+ @JsonProperty(COUNTRY)
protected String country;
public String getFormattedAddress() {
diff --git a/core/src/main/java/org/keycloak/representations/idm/ConfigPropertyRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ConfigPropertyRepresentation.java
new file mode 100755
index 0000000..0a96270
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/ConfigPropertyRepresentation.java
@@ -0,0 +1,53 @@
+package org.keycloak.representations.idm;
+
+/**
+* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+* @version $Revision: 1 $
+*/
+public class ConfigPropertyRepresentation {
+ protected String name;
+ protected String label;
+ protected String helpText;
+ protected String type;
+ protected Object defaultValue;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(Object defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getHelpText() {
+ return helpText;
+ }
+
+ public void setHelpText(String helpText) {
+ this.helpText = helpText;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperRepresentation.java
new file mode 100755
index 0000000..2d59ab8
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperRepresentation.java
@@ -0,0 +1,57 @@
+package org.keycloak.representations.idm;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class IdentityProviderMapperRepresentation {
+ protected String id;
+ protected String name;
+ protected String identityProviderAlias;
+ protected String identityProviderMapper;
+ protected Map<String, String> config = new HashMap<String, String>();
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getIdentityProviderAlias() {
+ return identityProviderAlias;
+ }
+
+ public void setIdentityProviderAlias(String identityProviderAlias) {
+ this.identityProviderAlias = identityProviderAlias;
+ }
+
+ public String getIdentityProviderMapper() {
+ return identityProviderMapper;
+ }
+
+ public void setIdentityProviderMapper(String identityProviderMapper) {
+ this.identityProviderMapper = identityProviderMapper;
+ }
+
+ public Map<String, String> getConfig() {
+ return config;
+ }
+
+ public void setConfig(Map<String, String> config) {
+ this.config = config;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperTypeRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperTypeRepresentation.java
new file mode 100755
index 0000000..c76f6ee
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderMapperTypeRepresentation.java
@@ -0,0 +1,56 @@
+package org.keycloak.representations.idm;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class IdentityProviderMapperTypeRepresentation {
+ protected String id;
+ protected String name;
+ protected String category;
+ protected String helpText;
+
+ protected List<ConfigPropertyRepresentation> properties;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getHelpText() {
+ return helpText;
+ }
+
+ public void setHelpText(String helpText) {
+ this.helpText = helpText;
+ }
+
+ public List<ConfigPropertyRepresentation> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(List<ConfigPropertyRepresentation> properties) {
+ this.properties = properties;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ProtocolMapperTypeRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ProtocolMapperTypeRepresentation.java
index 779f3be..212fe58 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ProtocolMapperTypeRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ProtocolMapperTypeRepresentation.java
@@ -12,55 +12,7 @@ public class ProtocolMapperTypeRepresentation {
protected String category;
protected String helpText;
- public static class ConfigProperty {
- protected String name;
- protected String label;
- protected String helpText;
- protected String type;
- protected Object defaultValue;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getLabel() {
- return label;
- }
-
- public void setLabel(String label) {
- this.label = label;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public Object getDefaultValue() {
- return defaultValue;
- }
-
- public void setDefaultValue(Object defaultValue) {
- this.defaultValue = defaultValue;
- }
-
- public String getHelpText() {
- return helpText;
- }
-
- public void setHelpText(String helpText) {
- this.helpText = helpText;
- }
- }
-
- protected List<ConfigProperty> properties;
+ protected List<ConfigPropertyRepresentation> properties;
public String getId() {
return id;
@@ -94,11 +46,11 @@ public class ProtocolMapperTypeRepresentation {
this.helpText = helpText;
}
- public List<ConfigProperty> getProperties() {
+ public List<ConfigPropertyRepresentation> getProperties() {
return properties;
}
- public void setProperties(List<ConfigProperty> properties) {
+ public void setProperties(List<ConfigPropertyRepresentation> properties) {
this.properties = properties;
}
}
diff --git a/core/src/main/java/org/keycloak/representations/IDToken.java b/core/src/main/java/org/keycloak/representations/IDToken.java
index 263ccb1..78fa5ce 100755
--- a/core/src/main/java/org/keycloak/representations/IDToken.java
+++ b/core/src/main/java/org/keycloak/representations/IDToken.java
@@ -13,76 +13,96 @@ import java.util.Map;
* @version $Revision: 1 $
*/
public class IDToken extends JsonWebToken {
+ public static final String NONCE = "nonce";
+ public static final String SESSION_STATE = "session_state";
+ public static final String NAME = "name";
+ public static final String GIVEN_NAME = "given_name";
+ public static final String FAMILY_NAME = "family_name";
+ public static final String MIDDLE_NAME = "middle_name";
+ public static final String NICKNAME = "nickname";
+ public static final String PREFERRED_USERNAME = "preferred_username";
+ public static final String PROFILE = "profile";
+ public static final String PICTURE = "picture";
+ public static final String WEBSITE = "website";
+ public static final String EMAIL = "email";
+ public static final String EMAIL_VERIFIED = "email_verified";
+ public static final String GENDER = "gender";
+ public static final String BIRTHDATE = "birthdate";
+ public static final String ZONEINFO = "zoneinfo";
+ public static final String LOCALE = "locale";
+ public static final String PHONE_NUMBER = "phone_number";
+ public static final String PHONE_NUMBER_VERIFIED = "phone_number_verified";
+ public static final String ADDRESS = "address";
+ public static final String UPDATED_AT = "updated_at";
+ public static final String CLAIMS_LOCALES = "claims_locales";
// NOTE!!! WE used to use @JsonUnwrapped on a UserClaimSet object. This screws up otherClaims and the won't work
// anymore. So don't have any @JsonUnwrapped!
- @JsonProperty("nonce")
+ @JsonProperty(NONCE)
protected String nonce;
- @JsonProperty("session_state")
+ @JsonProperty(SESSION_STATE)
protected String sessionState;
- @JsonProperty("name")
+ @JsonProperty(NAME)
protected String name;
- @JsonProperty("given_name")
+ @JsonProperty(GIVEN_NAME)
protected String givenName;
- @JsonProperty("family_name")
+ @JsonProperty(FAMILY_NAME)
protected String familyName;
- @JsonProperty("middle_name")
+ @JsonProperty(MIDDLE_NAME)
protected String middleName;
- @JsonProperty("nickname")
+ @JsonProperty(NICKNAME)
protected String nickName;
- @JsonProperty("preferred_username")
+ @JsonProperty(PREFERRED_USERNAME)
protected String preferredUsername;
- @JsonProperty("profile")
+ @JsonProperty(PROFILE)
protected String profile;
- @JsonProperty("picture")
+ @JsonProperty(PICTURE)
protected String picture;
- @JsonProperty("website")
+ @JsonProperty(WEBSITE)
protected String website;
- @JsonProperty("email")
+ @JsonProperty(EMAIL)
protected String email;
- @JsonProperty("email_verified")
+ @JsonProperty(EMAIL_VERIFIED)
protected Boolean emailVerified;
- @JsonProperty("gender")
+ @JsonProperty(GENDER)
protected String gender;
- @JsonProperty("birthdate")
+ @JsonProperty(BIRTHDATE)
protected String birthdate;
- @JsonProperty("zoneinfo")
+ @JsonProperty(ZONEINFO)
protected String zoneinfo;
- @JsonProperty("locale")
+ @JsonProperty(LOCALE)
protected String locale;
- @JsonProperty("phone_number")
+ @JsonProperty(PHONE_NUMBER)
protected String phoneNumber;
- @JsonProperty("phone_number_verified")
+ @JsonProperty(PHONE_NUMBER_VERIFIED)
protected Boolean phoneNumberVerified;
- @JsonProperty("address")
+ @JsonProperty(ADDRESS)
protected AddressClaimSet address;
- @JsonProperty("updated_at")
+ @JsonProperty(UPDATED_AT)
protected Long updatedAt;
- @JsonProperty("claims_locales")
+ @JsonProperty(CLAIMS_LOCALES)
protected String claimsLocales;
- protected Map<String, Object> otherClaims = new HashMap<String, Object>();
-
public String getNonce() {
return nonce;
}
@@ -259,18 +279,4 @@ public class IDToken extends JsonWebToken {
this.claimsLocales = claimsLocales;
}
- /**
- * This is a map of any other claims and data that might be in the IDToken. Could be custom claims set up by the auth server
- *
- * @return
- */
- @JsonAnyGetter
- public Map<String, Object> getOtherClaims() {
- return otherClaims;
- }
-
- @JsonAnySetter
- public void setOtherClaims(String name, Object value) {
- otherClaims.put(name, value);
- }
}
diff --git a/core/src/main/java/org/keycloak/representations/JsonWebToken.java b/core/src/main/java/org/keycloak/representations/JsonWebToken.java
index d0a4e9d..8db6ef3 100755
--- a/core/src/main/java/org/keycloak/representations/JsonWebToken.java
+++ b/core/src/main/java/org/keycloak/representations/JsonWebToken.java
@@ -1,10 +1,14 @@
package org.keycloak.representations;
+import org.codehaus.jackson.annotate.JsonAnyGetter;
+import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.keycloak.util.Time;
import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -29,6 +33,7 @@ public class JsonWebToken implements Serializable {
protected String type;
@JsonProperty("azp")
public String issuedFor;
+ protected Map<String, Object> otherClaims = new HashMap<String, Object>();
public String getId() {
return id;
@@ -153,4 +158,19 @@ public class JsonWebToken implements Serializable {
this.issuedFor = issuedFor;
return this;
}
+
+ /**
+ * This is a map of any other claims and data that might be in the IDToken. Could be custom claims set up by the auth server
+ *
+ * @return
+ */
+ @JsonAnyGetter
+ public Map<String, Object> getOtherClaims() {
+ return otherClaims;
+ }
+
+ @JsonAnySetter
+ public void setOtherClaims(String name, Object value) {
+ otherClaims.put(name, value);
+ }
}
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 dc1124a..a2bb17f 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
@@ -4,6 +4,7 @@ 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;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
@@ -18,6 +19,7 @@ import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentat
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
@@ -327,4 +329,16 @@ public class ModelToRepresentation {
return rep;
}
+ public static IdentityProviderMapperRepresentation toRepresentation(IdentityProviderMapperModel model) {
+ IdentityProviderMapperRepresentation rep = new IdentityProviderMapperRepresentation();
+ rep.setId(model.getId());
+ rep.setIdentityProviderMapper(model.getIdentityProviderMapper());
+ rep.setIdentityProviderAlias(model.getIdentityProviderAlias());
+ Map<String, String> config = new HashMap<String, String>();
+ config.putAll(model.getConfig());
+ rep.setConfig(config);
+ rep.setName(model.getName());
+ 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 f830ac1..6987151 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
@@ -9,6 +9,7 @@ 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;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.PasswordPolicy;
@@ -25,6 +26,7 @@ import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentat
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
@@ -870,6 +872,16 @@ public class RepresentationToModel {
return model;
}
+ public static IdentityProviderMapperModel toModel(IdentityProviderMapperRepresentation rep) {
+ IdentityProviderMapperModel model = new IdentityProviderMapperModel();
+ model.setId(rep.getId());
+ model.setName(rep.getName());
+ model.setIdentityProviderAlias(rep.getIdentityProviderAlias());
+ model.setIdentityProviderMapper(rep.getIdentityProviderMapper());
+ model.setConfig(rep.getConfig());
+ return model;
+ }
+
private static List<ClientIdentityProviderMappingModel> toModel(List<ClientIdentityProviderMappingRepresentation> repIdentityProviders, RealmModel realm) {
List<ClientIdentityProviderMappingModel> result = new ArrayList<ClientIdentityProviderMappingModel>();
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 bbb32b4..3f1983c 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
@@ -2,28 +2,40 @@ 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.broker.provider.IdentityProvider;
import org.keycloak.broker.provider.IdentityProviderFactory;
+import org.keycloak.broker.provider.IdentityProviderMapper;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientIdentityProviderMappingModel;
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.ModelDuplicateException;
+import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderFactory;
+import org.keycloak.representations.idm.ConfigPropertyRepresentation;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.services.resources.flows.Flows;
import org.keycloak.social.SocialIdentityProvider;
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;
@@ -31,6 +43,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
/**
@@ -45,6 +58,8 @@ public class IdentityProviderResource {
private final KeycloakSession session;
private final IdentityProviderModel identityProviderModel;
+ @Context private UriInfo uriInfo;
+
public IdentityProviderResource(RealmAuth auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel) {
this.realm = realm;
this.session = session;
@@ -56,6 +71,7 @@ public class IdentityProviderResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public IdentityProviderRepresentation getIdentityProvider() {
+ this.auth.requireView();
IdentityProviderRepresentation rep = ModelToRepresentation.toRepresentation(this.identityProviderModel);
return rep;
@@ -75,6 +91,7 @@ public class IdentityProviderResource {
@PUT
@Consumes(MediaType.APPLICATION_JSON)
+ @NoCache
public Response update(IdentityProviderRepresentation providerRep) {
try {
this.auth.requireManage();
@@ -163,6 +180,7 @@ public class IdentityProviderResource {
@GET
@Path("export")
+ @NoCache
public Response export(@Context UriInfo uriInfo, @QueryParam("format") String format) {
try {
this.auth.requireView();
@@ -173,6 +191,97 @@ public class IdentityProviderResource {
}
}
+ @GET
+ @Path("mapper-types")
+ @NoCache
+ public List<IdentityProviderMapperTypeRepresentation> getMapperTypes() {
+ this.auth.requireView();
+ KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
+ List<IdentityProviderMapperTypeRepresentation> types = new LinkedList<>();
+ List<ProviderFactory> factories = sessionFactory.getProviderFactories(IdentityProviderMapper.class);
+ for (ProviderFactory factory : factories) {
+ IdentityProviderMapper mapper = (IdentityProviderMapper)factory;
+ for (String type : mapper.getCompatibleProviders()) {
+ if (type.equals(identityProviderModel.getProviderId())) {
+ IdentityProviderMapperTypeRepresentation rep = new IdentityProviderMapperTypeRepresentation();
+ rep.setId(mapper.getId());
+ rep.setCategory(mapper.getDisplayCategory());
+ rep.setName(mapper.getDisplayType());
+ rep.setHelpText(mapper.getHelpText());
+ List<ProviderConfigProperty> configProperties = mapper.getConfigProperties();
+ for (ProviderConfigProperty prop : configProperties) {
+ ConfigPropertyRepresentation propRep = new ConfigPropertyRepresentation();
+ propRep.setName(prop.getName());
+ propRep.setLabel(prop.getLabel());
+ propRep.setType(prop.getType());
+ propRep.setDefaultValue(prop.getDefaultValue());
+ propRep.setHelpText(prop.getHelpText());
+ rep.getProperties().add(propRep);
+ }
+ types.add(rep);
+
+ }
+ }
+ }
+ return types;
+ }
+
+ @GET
+ @Path("mappers")
+ @Produces(MediaType.APPLICATION_JSON)
+ @NoCache
+ public List<IdentityProviderMapperRepresentation> getMappers() {
+ this.auth.requireView();
+ List<IdentityProviderMapperRepresentation> mappers = new LinkedList<>();
+ for (IdentityProviderMapperModel model : realm.getIdentityProviderMappersByAlias(identityProviderModel.getAlias())) {
+ mappers.add(ModelToRepresentation.toRepresentation(model));
+ }
+ return mappers;
+ }
+
+ @POST
+ @Path("mappers")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response addMapper(IdentityProviderMapperRepresentation mapper) {
+ auth.requireManage();
+ IdentityProviderMapperModel model = RepresentationToModel.toModel(mapper);
+ model = realm.addIdentityProviderMapper(model);
+ return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
+
+ }
+
+ @GET
+ @NoCache
+ @Path("mappers/{id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public IdentityProviderMapperRepresentation getMapperById(@PathParam("id") String id) {
+ auth.requireView();
+ IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ return ModelToRepresentation.toRepresentation(model);
+ }
+
+ @PUT
+ @NoCache
+ @Path("mappers/{id}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void update(@PathParam("id") String id, IdentityProviderMapperRepresentation rep) {
+ auth.requireManage();
+ IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ model = RepresentationToModel.toModel(rep);
+ realm.updateIdentityProviderMapper(model);
+ }
+
+ @DELETE
+ @NoCache
+ @Path("mappers/{id}")
+ public void delete(@PathParam("id") String id) {
+ auth.requireManage();
+ IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id);
+ if (model == null) throw new NotFoundException("Model not found");
+ realm.removeIdentityProviderMapper(model);
+ }
private void removeClientIdentityProviders(List<ClientModel> clients, IdentityProviderModel identityProvider) {
for (ClientModel clientModel : clients) {
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 0bdb525..f535b19 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
@@ -18,6 +18,7 @@ import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.Spi;
+import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
import org.keycloak.social.SocialIdentityProvider;
@@ -142,9 +143,10 @@ public class ServerInfoAdminResource {
rep.setName(mapper.getDisplayType());
rep.setHelpText(mapper.getHelpText());
rep.setCategory(mapper.getDisplayCategory());
- rep.setProperties(new LinkedList<ProtocolMapperTypeRepresentation.ConfigProperty>());
- for (ProviderConfigProperty prop : mapper.getConfigProperties()) {
- ProtocolMapperTypeRepresentation.ConfigProperty propRep = new ProtocolMapperTypeRepresentation.ConfigProperty();
+ rep.setProperties(new LinkedList<ConfigPropertyRepresentation>());
+ List<ProviderConfigProperty> configProperties = mapper.getConfigProperties();
+ for (ProviderConfigProperty prop : configProperties) {
+ ConfigPropertyRepresentation propRep = new ConfigPropertyRepresentation();
propRep.setName(prop.getName());
propRep.setLabel(prop.getLabel());
propRep.setType(prop.getType());
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 4098d33..7550eb8 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -23,10 +23,10 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.ClientConnection;
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.broker.provider.IdentityProvider;
import org.keycloak.broker.provider.IdentityProviderFactory;
+import org.keycloak.broker.provider.IdentityProviderMapper;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
@@ -34,11 +34,14 @@ import org.keycloak.events.EventType;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
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.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.services.managers.AppAuthManager;
@@ -71,6 +74,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
import static org.keycloak.models.ClientSessionModel.Action.AUTHENTICATE;
@@ -347,7 +351,16 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
LOGGER.debugf("Identity [%s] update with response from identity provider [%s].", federatedUser, updatedIdentity.getIdpConfig().getAlias());
}
}
- updatedIdentity.getIdp().updateBrokeredUser(federatedUser, updatedIdentity);
+ updatedIdentity.getIdp().updateBrokeredUser(session, realmModel, federatedUser, updatedIdentity);
+ Set<IdentityProviderMapperModel> mappers = realmModel.getIdentityProviderMappersByAlias(updatedIdentity.getIdpConfig().getAlias());
+ if (mappers != null) {
+ KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
+ for (IdentityProviderMapperModel mapper : mappers) {
+ IdentityProviderMapper target = (IdentityProviderMapper)sessionFactory.getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
+ target.updateBrokeredUser(session, realmModel, federatedUser, mapper, updatedIdentity);
+ }
+ }
+
}
private ClientSessionCode parseClientSessionCode(String code) {
@@ -520,7 +533,16 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
this.session.users().addFederatedIdentity(this.realmModel, federatedUser, federatedIdentityModel);
- updatedIdentity.getIdp().importNewUser(federatedUser, updatedIdentity);
+ updatedIdentity.getIdp().importNewUser(session, realmModel, federatedUser, updatedIdentity);
+ Set<IdentityProviderMapperModel> mappers = realmModel.getIdentityProviderMappersByAlias(updatedIdentity.getIdpConfig().getAlias());
+ if (mappers != null) {
+ KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
+ for (IdentityProviderMapperModel mapper : mappers) {
+ IdentityProviderMapper target = (IdentityProviderMapper)sessionFactory.getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
+ target.importNewUser(session, realmModel, federatedUser, mapper, updatedIdentity);
+ }
+ }
+
this.event.clone().user(federatedUser).event(EventType.REGISTER)
.detail(Details.IDENTITY_PROVIDER, federatedIdentityModel.getIdentityProvider())
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
index 4fc319a..cc9364f 100755
--- a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
@@ -5,7 +5,6 @@ import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.social.SocialIdentityProvider;
diff --git a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
index 978b4fe..ec56d15 100755
--- a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
+++ b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
@@ -5,7 +5,6 @@ import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.social.SocialIdentityProvider;
diff --git a/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java b/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java
index 9283ce5..911a55c 100755
--- a/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java
+++ b/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java
@@ -27,7 +27,6 @@ import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.social.SocialIdentityProvider;
diff --git a/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java b/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java
index 4ee77e8..f834464 100755
--- a/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java
+++ b/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java
@@ -28,7 +28,6 @@ import org.jboss.logging.Logger;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.social.SocialIdentityProvider;
diff --git a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java
index f8aebe2..b209fce 100755
--- a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java
+++ b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java
@@ -27,7 +27,6 @@ import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
import org.keycloak.broker.provider.AbstractIdentityProvider;
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.BrokeredIdentityContext;
-import org.keycloak.broker.provider.FederatedIdentity;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
@@ -36,8 +35,6 @@ import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.flows.Flows;
@@ -55,7 +52,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
-import java.util.HashMap;
import static org.keycloak.models.ClientSessionModel.Action.AUTHENTICATE;