keycloak-uncached
Changes
adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java 3(+1 -2)
adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java 4(+1 -3)
adapters/oidc/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java 5(+5 -0)
adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java 5(+5 -0)
adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java 38(+31 -7)
adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/JettyHttpFacade.java 5(+5 -0)
adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/ServletHttpFacade.java 5(+5 -0)
adapters/spi/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java 5(+5 -0)
adapters/spi/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/UndertowHttpFacade.java 5(+5 -0)
examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java 5(+5 -0)
federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPIdentityStore.java 29(+29 -0)
federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java 71(+70 -1)
federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/FullNameLDAPStorageMapper.java 25(+19 -6)
federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapper.java 34(+23 -11)
federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapperFactory.java 2(+1 -1)
federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java 8(+6 -2)
federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java 87(+2 -85)
saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java 3(+3 -0)
saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-4236-AttributeProfile-element.xml 180(+180 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/AbstractAuthorizationTest.java 8(+8 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPGroupMapperTest.java 8(+2 -6)
testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADFullNameTest.java 371(+371 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADMapperTest.java 176(+176 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java 7(+7 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSpecialCharsTest.java 31(+25 -6)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java 8(+6 -2)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java 67(+59 -8)
testsuite/integration-arquillian/pom.xml 33(+27 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java 7(+7 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java 17(+15 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java 5(+0 -5)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java 51(+46 -5)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerConfiguration.java 5(+5 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java 6(+6 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOIDCBrokerWithSignatureTest.java 17(+17 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java 7(+6 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java 2(+0 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java 20(+19 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java 9(+9 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/LegacyImportTest.java 22(+2 -20)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/AccountPageTest.java 25(+25 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java 79(+45 -34)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java 5(+5 -0)
Details
diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java
index 1673aa6..18a93a7 100644
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java
@@ -253,8 +253,7 @@ public abstract class AbstractPolicyEnforcer {
}
private String getPath(Request request) {
- String pathInfo = URI.create(request.getURI()).getPath().substring(1);
- return pathInfo.substring(pathInfo.indexOf('/'), pathInfo.length());
+ return request.getRelativePath();
}
private Set<String> getRequiredScopes(PathConfig pathConfig, Request request) {
diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
index 9f12420..fe8dfdc 100755
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
@@ -196,10 +196,8 @@ public class OAuthRequestAuthenticator {
return sslRedirectPort;
}
- protected static final AtomicLong counter = new AtomicLong();
-
protected String getStateCode() {
- return counter.getAndIncrement() + "/" + AdapterUtils.generateId();
+ return AdapterUtils.generateId();
}
protected AuthChallenge loginRedirect() {
diff --git a/adapters/oidc/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsHttpFacade.java b/adapters/oidc/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsHttpFacade.java
index 82ecc0b..1a0eb9c 100755
--- a/adapters/oidc/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsHttpFacade.java
+++ b/adapters/oidc/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsHttpFacade.java
@@ -67,6 +67,11 @@ public class JaxrsHttpFacade implements OIDCHttpFacade {
}
@Override
+ public String getRelativePath() {
+ return requestContext.getUriInfo().getPath();
+ }
+
+ @Override
public boolean isSecure() {
return securityContext.isSecure();
}
diff --git a/adapters/oidc/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java b/adapters/oidc/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
index 9660062..9e4fa0a 100755
--- a/adapters/oidc/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
+++ b/adapters/oidc/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
@@ -219,6 +219,11 @@ public class ServletOAuthClient extends KeycloakDeploymentDelegateOAuthClient {
}
@Override
+ public String getRelativePath() {
+ return servletRequest.getServletPath();
+ }
+
+ @Override
public boolean isSecure() {
return servletRequest.isSecure();
}
diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java
index e0cfd69..848ca45 100755
--- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java
+++ b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletRequest.java
@@ -71,6 +71,11 @@ class WrappedHttpServletRequest implements Request {
}
@Override
+ public String getRelativePath() {
+ return request.getServletPath();
+ }
+
+ @Override
public boolean isSecure() {
return request.isSecure();
}
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
index 1bbdf6d..cb9b4d9 100644
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
@@ -60,6 +60,7 @@ import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil;
import org.keycloak.saml.processing.web.util.PostBindingUtil;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.w3c.dom.Node;
import java.io.IOException;
@@ -70,14 +71,11 @@ import java.security.KeyManagementException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import org.keycloak.dom.saml.v2.SAML2Object;
import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
import org.keycloak.rotation.KeyLocator;
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
-import org.w3c.dom.Element;
/**
*
@@ -196,7 +194,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
challenge = new AuthChallenge() {
@Override
public boolean challenge(HttpFacade exchange) {
- SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE);
+ SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE, statusResponse);
exchange.getRequest().setError(error);
exchange.getResponse().sendError(403);
return true;
@@ -312,8 +310,25 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
return false;
}
- protected AuthOutcome handleLoginResponse(ResponseType responseType, boolean postBinding, OnSessionCreated onCreateSession) {
+ protected AuthOutcome handleLoginResponse(final ResponseType responseType, boolean postBinding, OnSessionCreated onCreateSession) {
AssertionType assertion = null;
+ if (! isSuccessfulSamlResponse(responseType) || responseType.getAssertions() == null || responseType.getAssertions().isEmpty()) {
+ challenge = new AuthChallenge() {
+ @Override
+ public boolean challenge(HttpFacade exchange) {
+ SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.ERROR_STATUS, responseType);
+ exchange.getRequest().setError(error);
+ exchange.getResponse().sendError(403);
+ return true;
+ }
+
+ @Override
+ public int getResponseCode() {
+ return 403;
+ }
+ };
+ return AuthOutcome.FAILED;
+ }
try {
assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey());
if (AssertionUtil.hasExpired(assertion)) {
@@ -335,6 +350,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
return 403;
}
};
+ return AuthOutcome.FAILED;
}
if (deployment.getIDP().getSingleSignOnService().validateAssertionSignature()) {
@@ -346,7 +362,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
challenge = new AuthChallenge() {
@Override
public boolean challenge(HttpFacade exchange) {
- SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE);
+ SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE, responseType);
exchange.getRequest().setError(error);
exchange.getResponse().sendError(403);
return true;
@@ -449,6 +465,14 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
return AuthOutcome.AUTHENTICATED;
}
+ private boolean isSuccessfulSamlResponse(ResponseType responseType) {
+ return responseType != null
+ && responseType.getStatus() != null
+ && responseType.getStatus().getStatusCode() != null
+ && responseType.getStatus().getStatusCode().getValue() != null
+ && Objects.equals(responseType.getStatus().getStatusCode().getValue().toString(), JBossSAMLURIConstants.STATUS_SUCCESS.get());
+ }
+
private String getAttributeValue(Object attrValue) {
String value = null;
if (attrValue instanceof String) {
diff --git a/adapters/spi/adapter-spi/src/main/java/org/keycloak/adapters/spi/HttpFacade.java b/adapters/spi/adapter-spi/src/main/java/org/keycloak/adapters/spi/HttpFacade.java
index a011824..2429286 100755
--- a/adapters/spi/adapter-spi/src/main/java/org/keycloak/adapters/spi/HttpFacade.java
+++ b/adapters/spi/adapter-spi/src/main/java/org/keycloak/adapters/spi/HttpFacade.java
@@ -44,6 +44,13 @@ public interface HttpFacade {
String getURI();
/**
+ * Get the request relative path.
+ *
+ * @return the request relative path
+ */
+ String getRelativePath();
+
+ /**
* HTTPS?
*
* @return
diff --git a/adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/JettyHttpFacade.java b/adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/JettyHttpFacade.java
index 2fc525e..dac7973 100755
--- a/adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/JettyHttpFacade.java
+++ b/adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/JettyHttpFacade.java
@@ -79,6 +79,11 @@ public class JettyHttpFacade implements HttpFacade {
}
@Override
+ public String getRelativePath() {
+ return request.getServletPath();
+ }
+
+ @Override
public String getFirstParam(String param) {
return request.getParameter(param);
}
diff --git a/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/ServletHttpFacade.java b/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/ServletHttpFacade.java
index 43349ab..6d99560 100755
--- a/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/ServletHttpFacade.java
+++ b/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/ServletHttpFacade.java
@@ -66,6 +66,11 @@ public class ServletHttpFacade implements HttpFacade {
}
@Override
+ public String getRelativePath() {
+ return request.getServletPath();
+ }
+
+ @Override
public boolean isSecure() {
return request.isSecure();
}
diff --git a/adapters/spi/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java b/adapters/spi/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java
index 315635d..c472564 100755
--- a/adapters/spi/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java
+++ b/adapters/spi/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java
@@ -79,6 +79,11 @@ public class CatalinaHttpFacade implements HttpFacade {
}
@Override
+ public String getRelativePath() {
+ return request.getServletPath();
+ }
+
+ @Override
public boolean isSecure() {
return request.isSecure();
}
diff --git a/adapters/spi/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/UndertowHttpFacade.java b/adapters/spi/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/UndertowHttpFacade.java
index a14e0b7..21102f1 100755
--- a/adapters/spi/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/UndertowHttpFacade.java
+++ b/adapters/spi/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/UndertowHttpFacade.java
@@ -84,6 +84,11 @@ public class UndertowHttpFacade implements HttpFacade {
}
@Override
+ public String getRelativePath() {
+ return exchange.getRelativePath();
+ }
+
+ @Override
public boolean isSecure() {
String protocol = exchange.getRequestScheme();
return protocol.equalsIgnoreCase("https");
diff --git a/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java b/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java
index 3783c12..cd912d7 100755
--- a/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java
+++ b/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java
@@ -182,6 +182,11 @@ public class OfflineAccessPortalServlet extends HttpServlet {
}
@Override
+ public String getRelativePath() {
+ return servletRequest.getServletPath();
+ }
+
+ @Override
public boolean isSecure() {
return servletRequest.isSecure();
}
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/model/LDAPDn.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/model/LDAPDn.java
index 8bfbf6d..94014fa 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/model/LDAPDn.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/model/LDAPDn.java
@@ -27,7 +27,15 @@ import java.util.LinkedList;
*/
public class LDAPDn {
- private final Deque<Entry> entries = new LinkedList<>();
+ private final Deque<Entry> entries;
+
+ private LDAPDn() {
+ this.entries = new LinkedList<>();
+ }
+
+ private LDAPDn(Deque<Entry> entries) {
+ this.entries = entries;
+ }
public static LDAPDn fromString(String dnString) {
LDAPDn dn = new LDAPDn();
@@ -115,12 +123,14 @@ public class LDAPDn {
/**
*
- * @return string like "dc=something,dc=org" from the DN like "uid=joe,dc=something,dc=org"
+ * @return DN like "dc=something,dc=org" from the DN like "uid=joe,dc=something,dc=org".
+ * Returned DN will be new clone not related to the original DN instance.
+ *
*/
- public String getParentDn() {
+ public LDAPDn getParentDn() {
LinkedList<Entry> parentDnEntries = new LinkedList<>(entries);
parentDnEntries.remove();
- return toString(parentDnEntries);
+ return new LDAPDn(parentDnEntries);
}
public boolean isDescendantOf(LDAPDn expectedParentDn) {
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPIdentityStore.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPIdentityStore.java
index c0e84b0..249a3a0 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPIdentityStore.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPIdentityStore.java
@@ -103,6 +103,8 @@ public class LDAPIdentityStore implements IdentityStore {
@Override
public void update(LDAPObject ldapObject) {
+ checkRename(ldapObject);
+
BasicAttributes updatedAttributes = extractAttributes(ldapObject, false);
NamingEnumeration<Attribute> attributes = updatedAttributes.getAll();
@@ -114,6 +116,33 @@ public class LDAPIdentityStore implements IdentityStore {
}
}
+ protected void checkRename(LDAPObject ldapObject) {
+ String rdnAttrName = ldapObject.getRdnAttributeName();
+ if (ldapObject.getReadOnlyAttributeNames().contains(rdnAttrName.toLowerCase())) {
+ return;
+ }
+
+ String rdnAttrVal = ldapObject.getAttributeAsString(rdnAttrName);
+
+ String oldRdnAttrVal = ldapObject.getDn().getFirstRdnAttrValue();
+ if (!oldRdnAttrVal.equals(rdnAttrVal)) {
+ LDAPDn newLdapDn = ldapObject.getDn().getParentDn();
+ newLdapDn.addFirst(rdnAttrName, rdnAttrVal);
+
+ String oldDn = ldapObject.getDn().toString();
+ String newDn = newLdapDn.toString();
+
+ if (logger.isDebugEnabled()) {
+ logger.debugf("Renaming LDAP Object. Old DN: [%s], New DN: [%s]", oldDn, newDn);
+ }
+
+ // In case, that there is conflict (For example already existing "CN=John Anthony"), the different DN is returned
+ newDn = this.operationManager.renameEntry(oldDn, newDn, true);
+
+ ldapObject.setDn(LDAPDn.fromString(newDn));
+ }
+ }
+
@Override
public void remove(LDAPObject ldapObject) {
this.operationManager.removeEntry(ldapObject.getDn().toString());
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java
index 350b16d..502fa75 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java
@@ -21,6 +21,7 @@ import org.jboss.logging.Logger;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.ModelException;
import org.keycloak.storage.ldap.LDAPConfig;
+import org.keycloak.storage.ldap.idm.model.LDAPDn;
import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
import org.keycloak.storage.ldap.mappers.LDAPOperationDecorator;
@@ -28,6 +29,7 @@ import javax.naming.AuthenticationException;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
+import javax.naming.NameAlreadyBoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
@@ -158,6 +160,64 @@ public class LDAPOperationManager {
}
}
+
+ /**
+ * Rename LDAPObject name (DN)
+ *
+ * @param oldDn
+ * @param newDn
+ * @param fallback With fallback=true, we will try to find the another DN in case of conflict. For example if there is an
+ * attempt to rename to "CN=John Doe", but there is already existing "CN=John Doe", we will try "CN=John Doe0"
+ * @return the non-conflicting DN, which was used in the end
+ */
+ public String renameEntry(String oldDn, String newDn, boolean fallback) {
+ try {
+ String newNonConflictingDn = execute(new LdapOperation<String>() {
+ @Override
+ public String execute(LdapContext context) throws NamingException {
+ String dn = newDn;
+
+ // Max 5 attempts for now
+ int max = 5;
+ for (int i=0 ; i<max ; i++) {
+ try {
+ context.rename(oldDn, dn);
+ return dn;
+ } catch (NameAlreadyBoundException ex) {
+ if (!fallback) {
+ throw ex;
+ } else {
+ String failedDn = dn;
+ if (i<max) {
+ dn = findNextDNForFallback(newDn, i);
+ logger.warnf("Failed to rename DN [%s] to [%s]. Will try to fallback to DN [%s]", oldDn, failedDn, dn);
+ } else {
+ logger.warnf("Failed all fallbacks for renaming [%s]", oldDn);
+ throw ex;
+ }
+ }
+ }
+ }
+
+ throw new ModelException("Could not rename entry from DN [" + oldDn + "] to new DN [" + newDn + "]. All fallbacks failed");
+ }
+ });
+ return newNonConflictingDn;
+ } catch (NamingException e) {
+ throw new ModelException("Could not rename entry from DN [" + oldDn + "] to new DN [" + newDn + "]", e);
+ }
+ }
+
+ private String findNextDNForFallback(String newDn, int counter) {
+ LDAPDn dn = LDAPDn.fromString(newDn);
+ String rdnAttrName = dn.getFirstRdnAttrName();
+ String rdnAttrVal = dn.getFirstRdnAttrValue();
+ LDAPDn parentDn = dn.getParentDn();
+ parentDn.addFirst(rdnAttrName, rdnAttrVal + counter);
+ return parentDn.toString();
+ }
+
+
public List<SearchResult> search(final String baseDN, final String filter, Collection<String> returningAttributes, int searchScope) throws NamingException {
final List<SearchResult> result = new ArrayList<SearchResult>();
final SearchControls cons = getSearchControls(returningAttributes, searchScope);
@@ -394,6 +454,11 @@ public class LDAPOperationManager {
values = "No values";
}
+ String attrName = item.getAttribute().getID().toUpperCase();
+ if (attrName.contains("PASSWORD") || attrName.contains("UNICODEPWD")) {
+ values = "********************";
+ }
+
logger.tracef(" Op [%s]: %s = %s", item.getModificationOp(), item.getAttribute().getID(), values);
}
@@ -540,7 +605,11 @@ public class LDAPOperationManager {
}
if (logger.isDebugEnabled()) {
- logger.debugf("Creating LdapContext using properties: [%s]", env);
+ Map<String, Object> copyEnv = new HashMap<>(env);
+ if (copyEnv.containsKey(Context.SECURITY_CREDENTIALS)) {
+ copyEnv.put(Context.SECURITY_CREDENTIALS, "**************************************");
+ }
+ logger.debugf("Creating LdapContext using properties: [%s]", copyEnv);
}
return env;
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPIdentityStoreRegistry.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPIdentityStoreRegistry.java
index 67d03f2..f6be118 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPIdentityStoreRegistry.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPIdentityStoreRegistry.java
@@ -20,11 +20,15 @@ package org.keycloak.storage.ldap;
import org.jboss.logging.Logger;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
import org.keycloak.storage.ldap.idm.store.ldap.LDAPIdentityStore;
import org.keycloak.storage.ldap.mappers.LDAPConfigDecorator;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -35,7 +39,7 @@ public class LDAPIdentityStoreRegistry {
private Map<String, LDAPIdentityStoreContext> ldapStores = new ConcurrentHashMap<>();
- public LDAPIdentityStore getLdapStore(ComponentModel ldapModel, Map<ComponentModel, LDAPConfigDecorator> configDecorators) {
+ public LDAPIdentityStore getLdapStore(KeycloakSession session, ComponentModel ldapModel, Map<ComponentModel, LDAPConfigDecorator> configDecorators) {
LDAPIdentityStoreContext context = ldapStores.get(ldapModel.getId());
// Ldap config might have changed for the realm. In this case, we must re-initialize
@@ -49,7 +53,7 @@ public class LDAPIdentityStoreRegistry {
}
if (context == null || !ldapConfig.equals(context.config)) {
- logLDAPConfig(ldapModel.getName(), ldapConfig);
+ logLDAPConfig(session, ldapModel, ldapConfig);
LDAPIdentityStore store = createLdapIdentityStore(ldapConfig);
context = new LDAPIdentityStoreContext(ldapConfig, store);
@@ -59,8 +63,18 @@ public class LDAPIdentityStoreRegistry {
}
// Don't log LDAP password
- private void logLDAPConfig(String fedProviderDisplayName, LDAPConfig ldapConfig) {
- logger.infof("Creating new LDAP Store for the LDAP storage provider: '%s', LDAP Configuration: %s", fedProviderDisplayName, ldapConfig.toString());
+ private void logLDAPConfig(KeycloakSession session, ComponentModel ldapModel, LDAPConfig ldapConfig) {
+ logger.infof("Creating new LDAP Store for the LDAP storage provider: '%s', LDAP Configuration: %s", ldapModel.getName(), ldapConfig.toString());
+
+ if (logger.isDebugEnabled()) {
+ RealmModel realm = session.realms().getRealm(ldapModel.getParentId());
+ List<ComponentModel> mappers = realm.getComponents(ldapModel.getId());
+ mappers.stream().forEach((ComponentModel c) -> {
+
+ logger.debugf("Mapper for provider: %s, Mapper name: %s, Provider: %s, Mapper configuration: %s", ldapModel.getName(), c.getName(), c.getProviderId(), c.getConfig().toString());
+
+ });
+ }
}
/**
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java
index 8edb6ca..7e112b1 100755
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java
@@ -92,6 +92,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
protected LDAPProviderKerberosConfig kerberosConfig;
protected PasswordUpdateCallback updater;
protected LDAPStorageMapperManager mapperManager;
+ protected LDAPStorageUserManager userManager;
protected final Set<String> supportedCredentialTypes = new HashSet<>();
@@ -103,6 +104,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
this.kerberosConfig = new LDAPProviderKerberosConfig(model);
this.editMode = ldapIdentityStore.getConfig().getEditMode();
this.mapperManager = new LDAPStorageMapperManager(this);
+ this.userManager = new LDAPStorageUserManager(this);
supportedCredentialTypes.add(UserCredentialModel.PASSWORD);
if (kerberosConfig.isAllowKerberosAuthentication()) {
@@ -134,6 +136,11 @@ public class LDAPStorageProvider implements UserStorageProvider,
return mapperManager;
}
+ public LDAPStorageUserManager getUserManager() {
+ return userManager;
+ }
+
+
@Override
public UserModel validate(RealmModel realm, UserModel local) {
LDAPObject ldapObject = loadAndValidateUser(realm, local);
@@ -145,6 +152,11 @@ public class LDAPStorageProvider implements UserStorageProvider,
}
protected UserModel proxy(RealmModel realm, UserModel local, LDAPObject ldapObject) {
+ UserModel existing = userManager.getManagedProxiedUser(local.getId());
+ if (existing != null) {
+ return existing;
+ }
+
UserModel proxied = local;
checkDNChanged(realm, local, ldapObject);
@@ -167,6 +179,8 @@ public class LDAPStorageProvider implements UserStorageProvider,
proxied = ldapMapper.proxy(ldapObject, proxied, realm);
}
+ userManager.setManagedProxiedUser(proxied, ldapObject);
+
return proxied;
}
@@ -227,6 +241,8 @@ public class LDAPStorageProvider implements UserStorageProvider,
}
ldapIdentityStore.remove(ldapObject);
+ userManager.removeManagedUserEntry(user.getId());
+
return true;
}
@@ -385,6 +401,11 @@ public class LDAPStorageProvider implements UserStorageProvider,
* @return ldapUser corresponding to local user or null if user is no longer in LDAP
*/
protected LDAPObject loadAndValidateUser(RealmModel realm, UserModel local) {
+ LDAPObject existing = userManager.getManagedLDAPUser(local.getId());
+ if (existing != null) {
+ return existing;
+ }
+
LDAPObject ldapUser = loadLDAPUserByUsername(realm, local.getUsername());
if (ldapUser == null) {
return null;
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java
index cd65604..6d60ee7 100755
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java
@@ -192,7 +192,7 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
public LDAPStorageProvider create(KeycloakSession session, ComponentModel model) {
Map<ComponentModel, LDAPConfigDecorator> configDecorators = getLDAPConfigDecorators(session, model);
- LDAPIdentityStore ldapIdentityStore = this.ldapStoreRegistry.getLdapStore(model, configDecorators);
+ LDAPIdentityStore ldapIdentityStore = this.ldapStoreRegistry.getLdapStore(session, model, configDecorators);
return new LDAPStorageProvider(this, session, model, ldapIdentityStore);
}
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageUserManager.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageUserManager.java
new file mode 100644
index 0000000..5155c12
--- /dev/null
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageUserManager.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.storage.ldap;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.keycloak.models.UserModel;
+import org.keycloak.storage.ldap.idm.model.LDAPObject;
+import org.keycloak.storage.ldap.mappers.LDAPTransaction;
+
+/**
+ * Track which LDAP users were already enlisted during this transaction
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class LDAPStorageUserManager {
+
+ private final Map<String, ManagedUserEntry> managedUsers = new HashMap<>();
+ private final LDAPStorageProvider provider;
+
+ public LDAPStorageUserManager(LDAPStorageProvider provider) {
+ this.provider = provider;
+ }
+
+ public UserModel getManagedProxiedUser(String userId) {
+ ManagedUserEntry entry = managedUsers.get(userId);
+ return entry==null ? null : entry.getManagedProxiedUser();
+ }
+
+ public LDAPObject getManagedLDAPUser(String userId) {
+ ManagedUserEntry entry = managedUsers.get(userId);
+ return entry==null ? null : entry.getLdapUser();
+ }
+
+ public LDAPTransaction getTransaction(String userId) {
+ ManagedUserEntry entry = managedUsers.get(userId);
+ if (entry == null) {
+ throw new IllegalStateException("Shouldn't happen to not have entry for userId: " + userId);
+ }
+
+ return entry.getLdapTransaction();
+
+ }
+
+ public void setManagedProxiedUser(UserModel proxiedUser, LDAPObject ldapObject) {
+ String userId = proxiedUser.getId();
+ ManagedUserEntry entry = managedUsers.get(userId);
+ if (entry != null) {
+ throw new IllegalStateException("Don't expect to have entry for user " + userId);
+ }
+
+ LDAPTransaction ldapTransaction = new LDAPTransaction(provider, ldapObject);
+ ManagedUserEntry newEntry = new ManagedUserEntry(proxiedUser, ldapObject, ldapTransaction);
+ managedUsers.put(userId, newEntry);
+ }
+
+ public void removeManagedUserEntry(String userId) {
+ managedUsers.remove(userId);
+ }
+
+
+
+ private static class ManagedUserEntry {
+
+ private final UserModel managedProxiedUser;
+ private final LDAPObject ldapUser;
+ private final LDAPTransaction ldapTransaction;
+
+ public ManagedUserEntry(UserModel managedProxiedUser, LDAPObject ldapUser, LDAPTransaction ldapTransaction) {
+ this.managedProxiedUser = managedProxiedUser;
+ this.ldapUser = ldapUser;
+ this.ldapTransaction = ldapTransaction;
+ }
+
+ public UserModel getManagedProxiedUser() {
+ return managedProxiedUser;
+ }
+
+ public LDAPObject getLdapUser() {
+ return ldapUser;
+ }
+
+ public LDAPTransaction getLdapTransaction() {
+ return ldapTransaction;
+ }
+ }
+}
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/FullNameLDAPStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/FullNameLDAPStorageMapper.java
index 43d631e..223a115 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/FullNameLDAPStorageMapper.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/FullNameLDAPStorageMapper.java
@@ -75,7 +75,7 @@ public class FullNameLDAPStorageMapper extends AbstractLDAPStorageMapper {
@Override
public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser, RealmModel realm) {
String ldapFullNameAttrName = getLdapFullNameAttrName();
- String fullName = getFullName(localUser.getFirstName(), localUser.getLastName());
+ String fullName = getFullNameForWriteToLDAP(localUser.getFirstName(), localUser.getLastName(), localUser.getUsername());
ldapUser.setSingleAttribute(ldapFullNameAttrName, fullName);
if (isReadOnly()) {
@@ -103,7 +103,7 @@ public class FullNameLDAPStorageMapper extends AbstractLDAPStorageMapper {
}
private void setFullNameToLDAPObject() {
- String fullName = getFullName(getFirstName(), getLastName());
+ String fullName = getFullNameForWriteToLDAP(getFirstName(), getLastName(), getUsername());
if (logger.isTraceEnabled()) {
logger.tracef("Pushing full name attribute to LDAP. Full name: %s", fullName);
}
@@ -177,18 +177,24 @@ public class FullNameLDAPStorageMapper extends AbstractLDAPStorageMapper {
return ldapFullNameAttrName == null ? LDAPConstants.CN : ldapFullNameAttrName;
}
- protected String getFullName(String firstName, String lastName) {
- if (firstName != null && lastName != null) {
+ protected String getFullNameForWriteToLDAP(String firstName, String lastName, String username) {
+ if (!isBlank(firstName) && !isBlank(lastName)) {
return firstName + " " + lastName;
- } else if (firstName != null) {
+ } else if (!isBlank(firstName)) {
return firstName;
- } else if (lastName != null) {
+ } else if (!isBlank(lastName)) {
return lastName;
+ } else if (isFallbackToUsername()) {
+ return username;
} else {
return LDAPConstants.EMPTY_ATTRIBUTE_VALUE;
}
}
+ private boolean isBlank(String attr) {
+ return attr == null || attr.trim().isEmpty();
+ }
+
private boolean isReadOnly() {
return parseBooleanParameter(mapperModel, READ_ONLY);
}
@@ -196,4 +202,11 @@ public class FullNameLDAPStorageMapper extends AbstractLDAPStorageMapper {
private boolean isWriteOnly() {
return parseBooleanParameter(mapperModel, WRITE_ONLY);
}
+
+
+ // Used just in case that we have Writable LDAP and fullName is mapped to "cn", which is used as RDN (this typically happens only on MSAD)
+ private boolean isFallbackToUsername() {
+ String rdnLdapAttrConfig = getLdapProvider().getLdapIdentityStore().getConfig().getRdnLdapAttribute();
+ return !isReadOnly() && getLdapFullNameAttrName().equalsIgnoreCase(rdnLdapAttrConfig);
+ }
}
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/LDAPTransaction.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/LDAPTransaction.java
new file mode 100644
index 0000000..1f2473b
--- /dev/null
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/LDAPTransaction.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.storage.ldap.mappers;
+
+import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.storage.ldap.LDAPStorageProvider;
+import org.keycloak.storage.ldap.idm.model.LDAPObject;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class LDAPTransaction implements KeycloakTransaction {
+
+ public static final Logger logger = Logger.getLogger(LDAPTransaction.class);
+
+ protected TransactionState state = TransactionState.NOT_STARTED;
+
+ private final LDAPStorageProvider ldapProvider;
+ private final LDAPObject ldapUser;
+
+ public LDAPTransaction(LDAPStorageProvider ldapProvider, LDAPObject ldapUser) {
+ this.ldapProvider = ldapProvider;
+ this.ldapUser = ldapUser;
+ }
+
+ @Override
+ public void begin() {
+ if (state != TransactionState.NOT_STARTED) {
+ throw new IllegalStateException("Transaction already started");
+ }
+
+ state = TransactionState.STARTED;
+ }
+
+ @Override
+ public void commit() {
+ if (state != TransactionState.STARTED) {
+ throw new IllegalStateException("Transaction in illegal state for commit: " + state);
+ }
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("Transaction commit! Updating LDAP attributes for object " + ldapUser.getDn().toString() + ", attributes: " + ldapUser.getAttributes());
+ }
+
+ ldapProvider.getLdapIdentityStore().update(ldapUser);
+ state = TransactionState.FINISHED;
+ }
+
+ @Override
+ public void rollback() {
+ if (state != TransactionState.STARTED && state != TransactionState.ROLLBACK_ONLY) {
+ throw new IllegalStateException("Transaction in illegal state for rollback: " + state);
+ }
+
+ logger.warn("Transaction rollback! Ignoring LDAP updates for object " + ldapUser.getDn().toString());
+ state = TransactionState.FINISHED;
+ }
+
+ @Override
+ public void setRollbackOnly() {
+ state = TransactionState.ROLLBACK_ONLY;
+ }
+
+ @Override
+ public boolean getRollbackOnly() {
+ return state == TransactionState.ROLLBACK_ONLY;
+ }
+
+ @Override
+ public boolean isActive() {
+ return state == TransactionState.STARTED || state == TransactionState.ROLLBACK_ONLY;
+ }
+
+
+ protected enum TransactionState {
+ NOT_STARTED, STARTED, ROLLBACK_ONLY, FINISHED
+ }
+}
+
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapper.java
index 4b926bb..efc0f0b 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapper.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapper.java
@@ -33,6 +33,7 @@ import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery;
import org.keycloak.storage.ldap.mappers.AbstractLDAPStorageMapper;
import org.keycloak.storage.ldap.mappers.LDAPOperationDecorator;
import org.keycloak.storage.ldap.mappers.PasswordUpdateCallback;
+import org.keycloak.storage.ldap.mappers.TxAwareLDAPUserModelDelegate;
import javax.naming.AuthenticationException;
import java.util.HashSet;
@@ -101,7 +102,7 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
control.remove(UserAccountControl.ACCOUNTDISABLE);
}
- updateUserAccountControl(ldapUser, control);
+ updateUserAccountControl(true, ldapUser, control);
}
@Override
@@ -142,11 +143,15 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) {
if (errorCode.equals("532") || errorCode.equals("773")) {
// User needs to change his MSAD password. Allow him to login, but add UPDATE_PASSWORD required action
- user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+ if (!user.getRequiredActions().contains(UserModel.RequiredAction.UPDATE_PASSWORD.name())) {
+ user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+ }
return true;
} else if (errorCode.equals("533")) {
// User is disabled in MSAD. Set him to disabled in KC as well
- user.setEnabled(false);
+ if (user.isEnabled()) {
+ user.setEnabled(false);
+ }
return true;
} else if (errorCode.equals("775")) {
logger.warnf("Locked user '%s' attempt to login", user.getUsername());
@@ -187,23 +192,26 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
return new UserAccountControl(longValue);
}
- // Update user in LDAP
- protected void updateUserAccountControl(LDAPObject ldapUser, UserAccountControl accountControl) {
+ // Update user in LDAP if "updateInLDAP" is true. Otherwise it is assumed that LDAP update will be called at the end of transaction
+ protected void updateUserAccountControl(boolean updateInLDAP, LDAPObject ldapUser, UserAccountControl accountControl) {
String userAccountControlValue = String.valueOf(accountControl.getValue());
logger.debugf("Updating userAccountControl of user '%s' to value '%s'", ldapUser.getDn().toString(), userAccountControlValue);
ldapUser.setSingleAttribute(LDAPConstants.USER_ACCOUNT_CONTROL, userAccountControlValue);
- ldapProvider.getLdapIdentityStore().update(ldapUser);
+
+ if (updateInLDAP) {
+ ldapProvider.getLdapIdentityStore().update(ldapUser);
+ }
}
- public class MSADUserModelDelegate extends UserModelDelegate {
+ public class MSADUserModelDelegate extends TxAwareLDAPUserModelDelegate {
private final LDAPObject ldapUser;
public MSADUserModelDelegate(UserModel delegate, LDAPObject ldapUser) {
- super(delegate);
+ super(delegate, ldapProvider, ldapUser);
this.ldapUser = ldapUser;
}
@@ -235,7 +243,9 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
control.add(UserAccountControl.ACCOUNTDISABLE);
}
- updateUserAccountControl(ldapUser, control);
+ ensureTransactionStarted();
+
+ updateUserAccountControl(false, ldapUser, control);
}
}
@@ -257,7 +267,8 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
ldapUser.removeReadOnlyAttributeName(LDAPConstants.PWD_LAST_SET);
ldapUser.setSingleAttribute(LDAPConstants.PWD_LAST_SET, "0");
- ldapProvider.getLdapIdentityStore().update(ldapUser);
+
+ ensureTransactionStarted();
}
}
@@ -283,7 +294,8 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
ldapUser.removeReadOnlyAttributeName(LDAPConstants.PWD_LAST_SET);
ldapUser.setSingleAttribute(LDAPConstants.PWD_LAST_SET, "-1");
- ldapProvider.getLdapIdentityStore().update(ldapUser);
+
+ ensureTransactionStarted();
}
}
}
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapperFactory.java
index 0eac7ae..81566f7 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapperFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msad/MSADUserAccountControlStorageMapperFactory.java
@@ -48,7 +48,7 @@ public class MSADUserAccountControlStorageMapperFactory extends AbstractLDAPStor
return ProviderConfigurationBuilder.create()
.property().name(MSADUserAccountControlStorageMapper.LDAP_PASSWORD_POLICY_HINTS_ENABLED)
.label("Password Policy Hints Enabled")
- .helpText("Applicable just for writable MSAD. If on, then updating password in MSAD will use LDAP_SERVER_POLICY_HINTS_OID " +
+ .helpText("Applicable just for writable MSAD. If on, then updating password of MSAD user will use LDAP_SERVER_POLICY_HINTS_OID " +
"extension, which means that advanced MSAD password policies like 'password history' or 'minimal password age' will be applied. This extension works just for MSAD 2008 R2 or newer.")
.type(ProviderConfigProperty.BOOLEAN_TYPE)
.defaultValue("false")
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java
index f10ac55..7276b31 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java
@@ -133,11 +133,15 @@ public class MSADLDSUserAccountControlStorageMapper extends AbstractLDAPStorageM
if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) {
if (errorCode.equals("532") || errorCode.equals("773")) {
// User needs to change his MSAD password. Allow him to login, but add UPDATE_PASSWORD required action
- user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+ if (!user.getRequiredActions().contains(UserModel.RequiredAction.UPDATE_PASSWORD.name())) {
+ user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+ }
return true;
} else if (errorCode.equals("533")) {
// User is disabled in MSAD LDS. Set him to disabled in KC as well
- user.setEnabled(false);
+ if (user.isEnabled()) {
+ user.setEnabled(false);
+ }
return true;
} else if (errorCode.equals("775")) {
logger.warnf("Locked user '%s' attempt to login", user.getUsername());
diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java
index 4fc5caf..2bf88f2 100644
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/TxAwareLDAPUserModelDelegate.java
@@ -18,7 +18,6 @@
package org.keycloak.storage.ldap.mappers;
import org.jboss.logging.Logger;
-import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.UserModelDelegate;
import org.keycloak.storage.ldap.LDAPStorageProvider;
@@ -33,39 +32,16 @@ public abstract class TxAwareLDAPUserModelDelegate extends UserModelDelegate {
protected LDAPStorageProvider provider;
protected LDAPObject ldapUser;
- private final LDAPTransaction transaction;
public TxAwareLDAPUserModelDelegate(UserModel delegate, LDAPStorageProvider provider, LDAPObject ldapUser) {
super(delegate);
this.provider = provider;
this.ldapUser = ldapUser;
- this.transaction = findOrCreateTransaction();
- }
-
- public LDAPTransaction getTransaction() {
- return transaction;
- }
-
- // Try to find transaction in any delegate. We want to enlist just single transaction per all delegates
- private LDAPTransaction findOrCreateTransaction() {
- UserModelDelegate delegate = this;
- while (true) {
- UserModel deleg = delegate.getDelegate();
- if (!(deleg instanceof UserModelDelegate)) {
- return new LDAPTransaction();
- } else {
- delegate = (UserModelDelegate) deleg;
- }
-
- if (delegate instanceof TxAwareLDAPUserModelDelegate) {
- TxAwareLDAPUserModelDelegate txDelegate = (TxAwareLDAPUserModelDelegate) delegate;
- return txDelegate.getTransaction();
- }
- }
}
protected void ensureTransactionStarted() {
- if (transaction.state == TransactionState.NOT_STARTED) {
+ LDAPTransaction transaction = provider.getUserManager().getTransaction(getId());
+ if (transaction.state == LDAPTransaction.TransactionState.NOT_STARTED) {
if (logger.isTraceEnabled()) {
logger.trace("Starting and enlisting transaction for object " + ldapUser.getDn().toString());
}
@@ -74,63 +50,4 @@ public abstract class TxAwareLDAPUserModelDelegate extends UserModelDelegate {
}
}
-
-
- protected class LDAPTransaction implements KeycloakTransaction {
-
- protected TransactionState state = TransactionState.NOT_STARTED;
-
- @Override
- public void begin() {
- if (state != TransactionState.NOT_STARTED) {
- throw new IllegalStateException("Transaction already started");
- }
-
- state = TransactionState.STARTED;
- }
-
- @Override
- public void commit() {
- if (state != TransactionState.STARTED) {
- throw new IllegalStateException("Transaction in illegal state for commit: " + state);
- }
-
- if (logger.isTraceEnabled()) {
- logger.trace("Transaction commit! Updating LDAP attributes for object " + ldapUser.getDn().toString() + ", attributes: " + ldapUser.getAttributes());
- }
-
- provider.getLdapIdentityStore().update(ldapUser);
- state = TransactionState.FINISHED;
- }
-
- @Override
- public void rollback() {
- if (state != TransactionState.STARTED && state != TransactionState.ROLLBACK_ONLY) {
- throw new IllegalStateException("Transaction in illegal state for rollback: " + state);
- }
-
- logger.warn("Transaction rollback! Ignoring LDAP updates for object " + ldapUser.getDn().toString());
- state = TransactionState.FINISHED;
- }
-
- @Override
- public void setRollbackOnly() {
- state = TransactionState.ROLLBACK_ONLY;
- }
-
- @Override
- public boolean getRollbackOnly() {
- return state == TransactionState.ROLLBACK_ONLY;
- }
-
- @Override
- public boolean isActive() {
- return state == TransactionState.STARTED || state == TransactionState.ROLLBACK_ONLY;
- }
- }
-
- protected enum TransactionState {
- NOT_STARTED, STARTED, ROLLBACK_ONLY, FINISHED
- }
-
}
diff --git a/federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/model/LDAPDnTest.java b/federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/model/LDAPDnTest.java
index a668cd7..d749c13 100644
--- a/federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/model/LDAPDnTest.java
+++ b/federation/ldap/src/test/java/org/keycloak/storage/ldap/idm/model/LDAPDnTest.java
@@ -35,7 +35,7 @@ public class LDAPDnTest {
Assert.assertEquals("uid=Johny\\,Depp\\+Pepp\\\\Foo,ou=People,dc=keycloak,dc=org", dn.toString());
Assert.assertEquals(LDAPDn.fromString("uid=Johny\\,Depp\\+Pepp\\\\Foo,ou=People,dc=keycloak,dc=org"), dn);
- Assert.assertEquals("ou=People,dc=keycloak,dc=org", dn.getParentDn());
+ Assert.assertEquals("ou=People,dc=keycloak,dc=org", dn.getParentDn().toString());
Assert.assertTrue(dn.isDescendantOf(LDAPDn.fromString("dc=keycloak, dc=org")));
Assert.assertTrue(dn.isDescendantOf(LDAPDn.fromString("dc=org")));
@@ -46,4 +46,22 @@ public class LDAPDnTest {
Assert.assertEquals("uid", dn.getFirstRdnAttrName());
Assert.assertEquals("Johny,Depp+Pepp\\Foo", dn.getFirstRdnAttrValue());
}
+
+ @Test
+ public void testCorrectEscape() throws Exception {
+ LDAPDn dn = LDAPDn.fromString("dc=keycloak, dc=org");
+ dn.addFirst("cn", "Johny,Džýa Foo");
+ Assert.assertEquals("cn=Johny\\,Džýa Foo,dc=keycloak,dc=org", dn.toString());
+ Assert.assertEquals("Johny,Džýa Foo", dn.getFirstRdnAttrValue());
+
+ dn = LDAPDn.fromString("dc=keycloak, dc=org");
+ dn.addFirst("cn", "Johny,Džýa Foo ");
+ Assert.assertEquals("cn=Johny\\,Džýa Foo\\ ,dc=keycloak,dc=org", dn.toString());
+ Assert.assertEquals("Johny,Džýa Foo ", dn.getFirstRdnAttrValue());
+
+ dn = LDAPDn.fromString("dc=keycloak, dc=org");
+ dn.addFirst("cn", "Johny,Džýa ");
+ Assert.assertEquals("cn=Johny\\,Džýa\\ ,dc=keycloak,dc=org", dn.toString());
+ Assert.assertEquals("Johny,Džýa ", dn.getFirstRdnAttrValue());
+ }
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java
index d61a611..52c1309 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java
@@ -616,7 +616,7 @@ public class RealmCacheSession implements CacheRealmProvider {
@Override
public RoleModel addRealmRole(RealmModel realm, String id, String name) {
- RoleModel role = getDelegate().addRealmRole(realm, name);
+ RoleModel role = getDelegate().addRealmRole(realm, id, name);
addedRole(role.getId(), realm.getId());
return role;
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java
index 41cb41d..00e41f3 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java
@@ -176,7 +176,7 @@ public class RoleAdapter implements RoleModel {
@Override
public boolean hasRole(RoleModel role) {
- return this.equals(role) || KeycloakModelUtils.searchFor(role, this);
+ return this.equals(role) || KeycloakModelUtils.searchFor(role, this, new HashSet<>());
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/PersistenceExceptionConverter.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/PersistenceExceptionConverter.java
index b79b9e5..def86cf 100644
--- a/model/jpa/src/main/java/org/keycloak/connections/jpa/PersistenceExceptionConverter.java
+++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/PersistenceExceptionConverter.java
@@ -55,7 +55,7 @@ public class PersistenceExceptionConverter implements InvocationHandler {
public static ModelException convert(Throwable t) {
if (t.getCause() != null && t.getCause() instanceof ConstraintViolationException) {
throw new ModelDuplicateException(t);
- } if (t instanceof EntityExistsException) {
+ } if (t instanceof EntityExistsException || t instanceof ConstraintViolationException) {
throw new ModelDuplicateException(t);
} else {
throw new ModelException(t);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
index 10e6252..39e24c3 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
@@ -128,7 +128,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
@Override
public boolean hasRole(RoleModel role) {
- return this.equals(role) || KeycloakModelUtils.searchFor(role, this);
+ return this.equals(role) || KeycloakModelUtils.searchFor(role, this, new HashSet<>());
}
@Override
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
index e141ff8..cf3c78f 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
@@ -172,7 +172,7 @@ public class RoleAdapter extends AbstractMongoAdapter<MongoRoleEntity> implement
@Override
public boolean hasRole(RoleModel role) {
- return this.equals(role) || KeycloakModelUtils.searchFor(role, this);
+ return this.equals(role) || KeycloakModelUtils.searchFor(role, this, new HashSet<>());
}
public MongoRoleEntity getRole() {
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java
index 2af29a3..5c3c30b 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java
@@ -363,6 +363,9 @@ public class SAMLEntityDescriptorParser extends AbstractDescriptorParser impleme
StaxParserUtil.validate(endElement, JBossSAMLConstants.ATTRIBUTE_SERVICE.get());
attributeAuthority.addAttributeService(endpoint);
+ } else if (JBossSAMLConstants.ATTRIBUTE_PROFILE.get().equalsIgnoreCase(localPart)) {
+ startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+ attributeAuthority.addAttributeProfile(StaxParserUtil.getElementText(xmlEventReader));
} else if (JBossSAMLConstants.KEY_DESCRIPTOR.get().equalsIgnoreCase(localPart)) {
attributeAuthority.addKeyDescriptor(parseKeyDescriptor(xmlEventReader));
} else if (JBossSAMLConstants.NAMEID_FORMAT.get().equalsIgnoreCase(localPart)) {
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java b/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
index 6da6799..5873a7f 100755
--- a/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
+++ b/saml-core/src/main/java/org/keycloak/saml/SAML2ErrorResponseBuilder.java
@@ -22,6 +22,7 @@ import java.util.List;
import org.keycloak.dom.saml.v2.assertion.NameIDType;
import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
import org.keycloak.dom.saml.v2.protocol.StatusResponseType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
import org.keycloak.saml.common.exceptions.ConfigurationException;
import org.keycloak.saml.common.exceptions.ParsingException;
import org.keycloak.saml.common.exceptions.ProcessingException;
@@ -66,7 +67,7 @@ public class SAML2ErrorResponseBuilder implements SamlProtocolExtensionsAwareBui
public Document buildDocument() throws ProcessingException {
try {
- StatusResponseType statusResponse = new StatusResponseType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
+ StatusResponseType statusResponse = new ResponseType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
statusResponse.setStatus(JBossSAMLAuthnResponseFactory.createStatusTypeForResponder(status));
NameIDType issuer = new NameIDType();
diff --git a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
index 51854fc..fdacdd7 100644
--- a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
+++ b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
@@ -155,4 +155,12 @@ public class SAMLParserTest {
assertThat(parsedObject, instanceOf(EntityDescriptorType.class));
}
}
+
+ @Test
+ public void testAttributeProfileMetadata() throws Exception {
+ try (InputStream st = SAMLParserTest.class.getResourceAsStream("KEYCLOAK-4236-AttributeProfile-element.xml")) {
+ Object parsedObject = parser.parse(st);
+ assertThat(parsedObject, instanceOf(EntityDescriptorType.class));
+ }
+ }
}
diff --git a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-4236-AttributeProfile-element.xml b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-4236-AttributeProfile-element.xml
new file mode 100644
index 0000000..14bdf8e
--- /dev/null
+++ b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-4236-AttributeProfile-element.xml
@@ -0,0 +1,180 @@
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#" xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:mdext="urn:oasis:names:tc:SAML:metadata:extension" xmlns:ns10="urn:oasis:names:tc:SAML:profiles:v1metadata" xmlns:query="urn:oasis:names:tc:SAML:metadata:ext:query" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="id-x-io4poU3tSqnNHhcDCTgbsMAMYMc-DQFWTm61QB" cacheDuration="P30DT0H0M0S" entityID="http://host.localdomain:14100/oam/fed" validUntil="2025-09-05T15:21:38Z">
+ <dsig:Signature>
+ <dsig:SignedInfo>
+ <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+ <dsig:Reference URI="#id-x-io4poU3tSqnNHhcDCTgbsMAMYMc-DQFWTm61QB">
+ <dsig:Transforms>
+ <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+ </dsig:Transforms>
+ <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+ <dsig:DigestValue>XKGk9TDAD9Exf4cz5B/HN4WyuII=</dsig:DigestValue>
+ </dsig:Reference>
+ </dsig:SignedInfo>
+ <dsig:SignatureValue>
+ C9dJFysqd2DsRSshxU8TIuqo1ECN5ASx6m8wT1sXxuBjQ1eitkgTs0ufC8P/t1aewOaDtg955+HTFnuOhV2r+rjoo8MY6Vrfdb14sj5UkTRU8Bv+ktnaPlBv+hKBVSwBVUwruSraTSaka7N42MfpteHupZGOcbeA3dSde/qg1AQ=
+ </dsig:SignatureValue>
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </dsig:Signature>
+ <md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:KeyDescriptor use="signing">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="encryption">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+ </md:KeyDescriptor>
+ <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://host.localdomain:14100/oamfed/idp/soap" index="1" isDefault="true"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://host.localdomain:14100/oamfed/idp/samlv20" ResponseLocation="http://host.localdomain:14100/oamfed/idp/samlv20"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://host.localdomain:14100/oamfed/idp/samlv20" ResponseLocation="http://host.localdomain:14100/oamfed/idp/samlv20"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://host.localdomain:14100/oamfed/idp/samlv20"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://host.localdomain:14100/oamfed/idp/soap"/>
+ <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://host.localdomain:14100/oamfed/idp/samlv20"/>
+ </md:IDPSSODescriptor>
+ <md:AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:KeyDescriptor use="signing">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="encryption">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+ </md:KeyDescriptor>
+ <md:AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://host.localdomain:14100/oamfed/aa/soap"/>
+ <md:AttributeProfile>
+ urn:oasis:names:tc:SAML:2.0:profiles:attribute:basic
+ </md:AttributeProfile>
+ </md:AttributeAuthorityDescriptor>
+ <md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <md:KeyDescriptor use="signing">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="encryption">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+ </md:KeyDescriptor>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://host.localdomain:14100/oamfed/sp/samlv20" ResponseLocation="http://host.localdomain:14100/oamfed/sp/samlv20"/>
+ <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://host.localdomain:14100/oamfed/sp/samlv20" ResponseLocation="http://host.localdomain:14100/oamfed/sp/samlv20"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://host.localdomain:14100/oam/server/fed/sp/sso" index="0" isDefault="true"/>
+ <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://host.localdomain:14100/oam/server/fed/sp/sso" index="1"/>
+ </md:SPSSODescriptor>
+ <md:RoleDescriptor WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" xsi:type="query:AttributeQueryDescriptorType">
+ <md:KeyDescriptor use="signing">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ </md:KeyDescriptor>
+ <md:KeyDescriptor use="encryption">
+ <dsig:KeyInfo>
+ <dsig:X509Data>
+ <dsig:X509Certificate>
+ MIIB/DCCAWWgAwIBAgIBCjANBgkqhkiG9w0BAQQFADAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wHhcNMTUwOTA4MTUyMTM4WhcNMjUwOTA1MTUyMTM4WjAjMSEwHwYDVQQDExhvYW1zZXJ2ZXJwczMubG9jYWxkb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIYXVJI+3G8AL/8sRC2BRVc9uGZudAuc/KZARTwK5+fEJywBSOnB+p+MCYjDTkCOehtK7V3UX/lXJvkQwSBaAl938RUNyW5WcOV+mi0C8yqR8VEAHL4EqnikUtOD7kysp0FNBT+Z71G6c4kJ2fszZyggiUUdjPuQHSqHFB4smfQrAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwfYADAdBgNVHQ4EFgQUql4UpKGYI9j30VJGuJkBoTqCwjAwDQYJKoZIhvcNAQEEBQADgYEAc9du+MB7/uZDd73JX5/31naQnW0GvORIH5hszlp8c8Z7KlQzfwxLgldK5RCO61Qw10LjYARZiVm/1YhsRJ5qRWeMDfO4+soTBgMd2/dyyp25RsmEoANMToB1CWGWujlB2L/A33dU6Zbo1qtsuxhfQg1mYHd935+Xyd8j8175/mk=
+ </dsig:X509Certificate>
+ <dsig:X509IssuerSerial>
+ <dsig:X509IssuerName>CN=host.localdomain</dsig:X509IssuerName>
+ <dsig:X509SerialNumber>10</dsig:X509SerialNumber>
+ </dsig:X509IssuerSerial>
+ <dsig:X509SubjectName>CN=host.localdomain</dsig:X509SubjectName>
+ </dsig:X509Data>
+ </dsig:KeyInfo>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+ <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+ </md:KeyDescriptor>
+ </md:RoleDescriptor>
+</md:EntityDescriptor>
\ No newline at end of file
diff --git a/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java b/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
index d0b8b85..fd6acd4 100755
--- a/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
+++ b/saml-core-api/src/main/java/org/keycloak/saml/common/constants/JBossSAMLConstants.java
@@ -29,7 +29,7 @@ public enum JBossSAMLConstants {
"AssertionConsumerService"), ASSERTION_CONSUMER_SERVICE_URL("AssertionConsumerServiceURL"), ASSERTION_CONSUMER_SERVICE_INDEX(
"AssertionConsumerServiceIndex"), ASSERTION_ID_REQUEST_SERVICE("AssertionIDRequestService"), ATTRIBUTE("Attribute"), ATTRIBUTE_QUERY(
"AttributeQuery"), ATTRIBUTE_AUTHORITY_DESCRIPTOR("AttributeAuthorityDescriptor"), ATTRIBUTE_CONSUMING_SERVICE(
- "AttributeConsumingService"), ATTRIBUTE_CONSUMING_SERVICE_INDEX("AttributeConsumingServiceIndex"), ATTRIBUTE_SERVICE(
+ "AttributeConsumingService"), ATTRIBUTE_CONSUMING_SERVICE_INDEX("AttributeConsumingServiceIndex"), ATTRIBUTE_PROFILE("AttributeProfile"), ATTRIBUTE_SERVICE(
"AttributeService"), ATTRIBUTE_STATEMENT("AttributeStatement"), ATTRIBUTE_VALUE("AttributeValue"), AUDIENCE(
"Audience"), AUDIENCE_RESTRICTION("AudienceRestriction"), AUTHN_CONTEXT("AuthnContext"), AUTHENTICATING_AUTHORITY(
"AuthenticatingAuthority"), AUTHN_AUTHORITY_DESCRIPTOR("AuthnAuthorityDescriptor"), AUTHN_CONTEXT_CLASS_REF(
diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index a258cd7..695fe38 100755
--- a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -177,14 +177,23 @@ public final class KeycloakModelUtils {
* @param visited set of already visited roles (used for recursion)
* @return true if "role" is descendant of "composite"
*/
- public static boolean searchFor(RoleModel role, RoleModel composite) {
- return composite.isComposite() && (
- composite.getComposites().contains(role) ||
- composite.getComposites().stream()
- .filter(x -> x.isComposite() && x.hasRole(role))
+ public static boolean searchFor(RoleModel role, RoleModel composite, Set<String> visited) {
+ if (visited.contains(composite.getId())) {
+ return false;
+ }
+
+ visited.add(composite.getId());
+
+ if (!composite.isComposite()) {
+ return false;
+ }
+
+ Set<RoleModel> compositeRoles = composite.getComposites();
+ return compositeRoles.contains(role) ||
+ compositeRoles.stream()
+ .filter(x -> x.isComposite() && searchFor(role, x, visited))
.findFirst()
- .isPresent()
- );
+ .isPresent();
}
/**
diff --git a/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java b/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
index 39a9d2e..38e57cb 100755
--- a/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
+++ b/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
@@ -19,6 +19,7 @@ package org.keycloak.broker.saml;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
+
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.broker.provider.IdentityProvider;
@@ -78,10 +79,13 @@ import java.security.Key;
import java.security.cert.X509Certificate;
import java.util.LinkedList;
import java.util.List;
+
import org.keycloak.rotation.HardcodedKeyLocator;
import org.keycloak.rotation.KeyLocator;
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
+import java.util.*;
+
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@@ -333,6 +337,13 @@ public class SAMLEndpoint {
try {
KeyManager.ActiveRsaKey keys = session.keys().getActiveRsaKey(realm);
+ if (! isSuccessfulSamlResponse(responseType)) {
+ String statusMessage = responseType.getStatus() == null ? Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR : responseType.getStatus().getStatusMessage();
+ return callback.error(relayState, statusMessage);
+ }
+ if (responseType.getAssertions() == null || responseType.getAssertions().isEmpty()) {
+ return callback.error(relayState, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
+ }
AssertionType assertion = AssertionUtil.getAssertion(responseType, keys.getPrivateKey());
SubjectType subject = assertion.getSubject();
SubjectType.STSubType subType = subject.getSubType();
@@ -395,6 +406,13 @@ public class SAMLEndpoint {
}
+ private boolean isSuccessfulSamlResponse(ResponseType responseType) {
+ return responseType != null
+ && responseType.getStatus() != null
+ && responseType.getStatus().getStatusCode() != null
+ && responseType.getStatus().getStatusCode().getValue() != null
+ && Objects.equals(responseType.getStatus().getStatusCode().getValue().toString(), JBossSAMLURIConstants.STATUS_SUCCESS.get());
+ }
public Response handleSamlResponse(String samlResponse, String relayState, String clientId) {
diff --git a/services/src/main/java/org/keycloak/keys/loader/HardcodedPublicKeyLoader.java b/services/src/main/java/org/keycloak/keys/loader/HardcodedPublicKeyLoader.java
new file mode 100644
index 0000000..b5cbbde
--- /dev/null
+++ b/services/src/main/java/org/keycloak/keys/loader/HardcodedPublicKeyLoader.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.keys.loader;
+
+import org.keycloak.common.util.PemUtils;
+import org.keycloak.keys.PublicKeyLoader;
+
+import java.security.PublicKey;
+import java.util.*;
+
+/**
+ *
+ * @author hmlnarik
+ */
+public class HardcodedPublicKeyLoader implements PublicKeyLoader {
+
+ private final String kid;
+ private final String pem;
+
+ public HardcodedPublicKeyLoader(String kid, String pem) {
+ this.kid = kid;
+ this.pem = pem;
+ }
+
+ @Override
+ public Map<String, PublicKey> loadKeys() throws Exception {
+ return Collections.unmodifiableMap(Collections.singletonMap(kid, getSavedPublicKey()));
+ }
+
+ protected PublicKey getSavedPublicKey() {
+ if (pem != null && ! pem.trim().equals("")) {
+ return PemUtils.decodePublicKey(pem);
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/services/src/main/java/org/keycloak/keys/loader/PublicKeyStorageManager.java b/services/src/main/java/org/keycloak/keys/loader/PublicKeyStorageManager.java
index d4507e9..30aae3f 100644
--- a/services/src/main/java/org/keycloak/keys/loader/PublicKeyStorageManager.java
+++ b/services/src/main/java/org/keycloak/keys/loader/PublicKeyStorageManager.java
@@ -21,17 +21,20 @@ import java.security.PublicKey;
import org.keycloak.broker.oidc.OIDCIdentityProviderConfig;
import org.keycloak.jose.jws.JWSInput;
-import org.keycloak.keys.PublicKeyStorageProvider;
-import org.keycloak.keys.PublicKeyStorageUtils;
+import org.keycloak.keys.*;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
+import org.jboss.logging.Logger;
+
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class PublicKeyStorageManager {
+ private static final Logger logger = Logger.getLogger(PublicKeyStorageManager.class);
+
public static PublicKey getClientPublicKey(KeycloakSession session, ClientModel client, JWSInput input) {
String kid = input.getHeader().getKeyId();
@@ -44,13 +47,31 @@ public class PublicKeyStorageManager {
public static PublicKey getIdentityProviderPublicKey(KeycloakSession session, RealmModel realm, OIDCIdentityProviderConfig idpConfig, JWSInput input) {
+ boolean keyIdSetInConfiguration = idpConfig.getPublicKeySignatureVerifierKeyId() != null
+ && ! idpConfig.getPublicKeySignatureVerifierKeyId().trim().isEmpty();
+
String kid = input.getHeader().getKeyId();
PublicKeyStorageProvider keyStorage = session.getProvider(PublicKeyStorageProvider.class);
String modelKey = PublicKeyStorageUtils.getIdpModelCacheKey(realm.getId(), idpConfig.getInternalId());
- OIDCIdentityProviderPublicKeyLoader loader = new OIDCIdentityProviderPublicKeyLoader(session, idpConfig);
+ PublicKeyLoader loader;
+ if (idpConfig.isUseJwksUrl()) {
+ loader = new OIDCIdentityProviderPublicKeyLoader(session, idpConfig);
+ } else {
+ String pem = idpConfig.getPublicKeySignatureVerifier();
+
+ if (pem == null || pem.trim().isEmpty()) {
+ logger.warnf("No public key saved on identityProvider %s", idpConfig.getAlias());
+ return null;
+ }
+
+ loader = new HardcodedPublicKeyLoader(
+ keyIdSetInConfiguration
+ ? idpConfig.getPublicKeySignatureVerifierKeyId().trim()
+ : kid, pem);
+ }
+
return keyStorage.getPublicKey(modelKey, kid, loader);
}
-
}
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 6072af9..5e1e247 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -66,6 +66,8 @@ import org.keycloak.common.util.Time;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
+
+import java.security.PublicKey;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -287,7 +289,17 @@ public class TokenManager {
public RefreshToken toRefreshToken(KeycloakSession session, RealmModel realm, String encodedRefreshToken) throws JWSInputException, OAuthErrorException {
JWSInput jws = new JWSInput(encodedRefreshToken);
- if (!RSAProvider.verify(jws, session.keys().getRsaPublicKey(realm, jws.getHeader().getKeyId()))) {
+ PublicKey publicKey;
+
+ // Backwards compatibility. Old offline tokens didn't have KID in the header
+ if (jws.getHeader().getKeyId() == null && TokenUtil.isOfflineToken(encodedRefreshToken)) {
+ logger.debugf("KID is null in offline token. Using the realm active key to verify token signature.");
+ publicKey = session.keys().getActiveRsaKey(realm).getPublicKey();
+ } else {
+ publicKey = session.keys().getRsaPublicKey(realm, jws.getHeader().getKeyId());
+ }
+
+ if (!RSAProvider.verify(jws, publicKey)) {
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Invalid refresh token");
}
diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
index 8c6f03c..6759fb6 100755
--- a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
@@ -161,13 +161,15 @@ public class SamlProtocol implements LoginProtocol {
@Override
public Response sendError(ClientSessionModel clientSession, Error error) {
try {
- if ("true".equals(clientSession.getClient().getAttribute(SAML_IDP_INITIATED_LOGIN))) {
+ ClientModel client = clientSession.getClient();
+
+ if ("true".equals(client.getAttribute(SAML_IDP_INITIATED_LOGIN))) {
if (error == Error.CANCELLED_BY_USER) {
UriBuilder builder = RealmsResource.protocolUrl(uriInfo).path(SamlService.class, "idpInitiatedSSO");
Map<String, String> params = new HashMap<>();
params.put("realm", realm.getName());
params.put("protocol", LOGIN_PROTOCOL);
- params.put("client", clientSession.getClient().getAttribute(SAML_IDP_INITIATED_SSO_URL_NAME));
+ params.put("client", client.getAttribute(SAML_IDP_INITIATED_SSO_URL_NAME));
URI redirect = builder.buildFromMap(params);
return Response.status(302).location(redirect).build();
} else {
@@ -177,6 +179,27 @@ public class SamlProtocol implements LoginProtocol {
SAML2ErrorResponseBuilder builder = new SAML2ErrorResponseBuilder().destination(clientSession.getRedirectUri()).issuer(getResponseIssuer(realm)).status(translateErrorToSAMLStatus(error).get());
try {
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder().relayState(clientSession.getNote(GeneralConstants.RELAY_STATE));
+ SamlClient samlClient = new SamlClient(client);
+ KeyManager keyManager = session.keys();
+ if (samlClient.requiresRealmSignature()) {
+ KeyManager.ActiveRsaKey keys = keyManager.getActiveRsaKey(realm);
+ String keyName = samlClient.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
+ String canonicalization = samlClient.getCanonicalizationMethod();
+ if (canonicalization != null) {
+ binding.canonicalizationMethod(canonicalization);
+ }
+ binding.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
+ }
+ if (samlClient.requiresEncryption()) {
+ PublicKey publicKey;
+ try {
+ publicKey = SamlProtocolUtils.getEncryptionValidationKey(client);
+ } catch (Exception e) {
+ logger.error("failed", e);
+ return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
+ }
+ binding.encrypt(publicKey);
+ }
Document document = builder.buildDocument();
return buildErrorResponse(clientSession, binding, document);
} catch (Exception e) {
diff --git a/services/src/main/java/org/keycloak/theme/beans/MessageFormatterMethod.java b/services/src/main/java/org/keycloak/theme/beans/MessageFormatterMethod.java
index 38748c7..dfb737d 100755
--- a/services/src/main/java/org/keycloak/theme/beans/MessageFormatterMethod.java
+++ b/services/src/main/java/org/keycloak/theme/beans/MessageFormatterMethod.java
@@ -17,10 +17,13 @@
package org.keycloak.theme.beans;
+import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
+import org.keycloak.theme.TemplatingUtil;
import java.text.MessageFormat;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
@@ -40,10 +43,27 @@ public class MessageFormatterMethod implements TemplateMethodModelEx {
@Override
public Object exec(List list) throws TemplateModelException {
if (list.size() >= 1) {
+ // resolve any remaining ${} expressions
+ List<Object> resolved = resolve(list.subList(1, list.size()));
String key = list.get(0).toString();
- return new MessageFormat(messages.getProperty(key,key),locale).format(list.subList(1, list.size()).toArray());
+ return new MessageFormat(messages.getProperty(key,key),locale).format(resolved.toArray());
} else {
return null;
}
}
+
+ private List<Object> resolve(List<Object> list) {
+ ArrayList<Object> result = new ArrayList<>();
+ for (Object item: list) {
+ if (item instanceof SimpleScalar) {
+ item = ((SimpleScalar) item).getAsString();
+ }
+ if (item instanceof String) {
+ result.add(TemplatingUtil.resolveVariables((String) item, messages));
+ } else {
+ result.add(item);
+ }
+ }
+ return result;
+ }
}
diff --git a/services/src/main/java/org/keycloak/theme/TemplatingUtil.java b/services/src/main/java/org/keycloak/theme/TemplatingUtil.java
new file mode 100644
index 0000000..f1fc912
--- /dev/null
+++ b/services/src/main/java/org/keycloak/theme/TemplatingUtil.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.theme;
+
+import java.util.Properties;
+
+/**
+ * @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
+ */
+public class TemplatingUtil {
+
+ public static String resolveVariables(String text, Properties props) {
+ return resolveVariables(text, props, "${", "}");
+ }
+
+ public static String resolveVariables(String text, Properties props, String startMarker, String endMarker) {
+
+ int e = 0;
+ int s = text.indexOf(startMarker);
+ if (s == -1) {
+ return text;
+ } else {
+ StringBuilder sb = new StringBuilder();
+
+ do {
+ if (e < s) {
+ sb.append(text.substring(e, s));
+ }
+ e = text.indexOf(endMarker, s + startMarker.length());
+ if (e != -1) {
+ String key = text.substring(s + startMarker.length(), e);
+ sb.append(props.getProperty(key, key));
+ e += endMarker.length();
+ s = text.indexOf(startMarker, e);
+ } else {
+ e = s;
+ break;
+ }
+ } while (s != -1);
+
+ if (e < text.length()) {
+ sb.append(text.substring(e));
+ }
+ return sb.toString();
+ }
+ }
+}
diff --git a/services/src/test/java/org/keycloak/theme/beans/MessageFormatterMethodTest.java b/services/src/test/java/org/keycloak/theme/beans/MessageFormatterMethodTest.java
new file mode 100644
index 0000000..98f095e
--- /dev/null
+++ b/services/src/test/java/org/keycloak/theme/beans/MessageFormatterMethodTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.theme.beans;
+
+import freemarker.template.TemplateModelException;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Properties;
+
+/**
+ * @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
+ */
+public class MessageFormatterMethodTest {
+
+ @Test
+ public void test() throws TemplateModelException {
+
+ Locale locale = Locale.US;
+
+ Properties properties = new Properties();
+ properties.setProperty("backToApplication", "Back to application");
+ properties.setProperty("backToClient", "Back to {0}");
+ properties.setProperty("client_admin-console", "Admin Console");
+ properties.setProperty("realm_example-realm", "Example Realm");
+
+
+ MessageFormatterMethod fmt = new MessageFormatterMethod(locale, properties);
+
+ String msg = (String) fmt.exec(Arrays.asList("backToClient", "${client_admin-console}"));
+ Assert.assertEquals("Back to Admin Console", msg);
+
+ msg = (String) fmt.exec(Arrays.asList("backToClient", "client_admin-console"));
+ Assert.assertEquals("Back to client_admin-console", msg);
+
+ msg = (String) fmt.exec(Arrays.asList("backToClient", "client '${client_admin-console}' from '${realm_example-realm}'."));
+ Assert.assertEquals("Back to client 'Admin Console' from 'Example Realm'.", msg);
+ }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/AbstractAuthorizationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/AbstractAuthorizationTest.java
index ebf7144..2bea843 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/AbstractAuthorizationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/AbstractAuthorizationTest.java
@@ -18,10 +18,13 @@
package org.keycloak.testsuite.authorization;
+import org.junit.Assume;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.authorization.AuthorizationProvider;
+import org.keycloak.common.Profile;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
@@ -51,6 +54,11 @@ public abstract class AbstractAuthorizationTest {
private Keycloak adminClient;
+ @BeforeClass
+ public static void enabled() {
+ Assume.assumeTrue("Ignoring test as community/preview profile is not enabled", !Profile.getName().equals("product"));
+ }
+
@Before
public void onBefore() {
adminClient = Keycloak.getInstance(AUTH_SERVER_ROOT, MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPGroupMapperTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPGroupMapperTest.java
index e36f8e8..a25fe0f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPGroupMapperTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPGroupMapperTest.java
@@ -109,7 +109,6 @@ public class LDAPGroupMapperTest {
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group1", descriptionAttrName, "group1 - description");
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group11");
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group12", descriptionAttrName, "group12 - description");
- LDAPObject groupSpecialCharacters = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group-spec,ia*l_characžter)s", descriptionAttrName, "group-special-characters");
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11, false);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12, true);
@@ -134,14 +133,11 @@ public class LDAPGroupMapperTest {
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
- LDAPObject james2 = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jamees,key*cložak)ppp", "James2", "Brown2", "james2@email.org", null, "89102");
- LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james2, "Password1");
-
- postSetup();
+ postSetup(appRealm, ldapFedProvider);
}
- void postSetup() {
+ void postSetup(RealmModel appRealm, LDAPStorageProvider ldapProvider) {
LDAPGroupMapperTest.ldapModel = this.ldapModel;
LDAPGroupMapperTest.descriptionAttrName = this.descriptionAttrName;
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADFullNameTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADFullNameTest.java
new file mode 100644
index 0000000..e893d55
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADFullNameTest.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.federation.storage.ldap;
+
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runners.MethodSorters;
+import org.keycloak.common.util.MultivaluedHashMap;
+import org.keycloak.component.ComponentModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.LDAPConstants;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.storage.UserStorageProvider;
+import org.keycloak.storage.UserStorageProviderModel;
+import org.keycloak.storage.ldap.LDAPStorageProvider;
+import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
+import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
+import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
+import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AccountPasswordPage;
+import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
+import org.keycloak.testsuite.pages.AppPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.LDAPRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * Test for the MSAD setup with usernameAttribute=sAMAccountName, rdnAttribute=cn and fullNameMapper mapped to cn
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class LDAPMSADFullNameTest {
+
+ // Run this test just on MSAD and just when sAMAccountName is mapped to username
+ private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
+
+ String vendor = ldapConfig.get(LDAPConstants.VENDOR);
+ if (!vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY)) {
+ return true;
+ }
+
+ String usernameAttr = ldapConfig.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
+ return !usernameAttr.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME);
+
+ });
+
+ private static ComponentModel ldapModel = null;
+
+ private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
+
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
+
+ MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
+ ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
+ ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
+ UserStorageProviderModel model = new UserStorageProviderModel();
+ model.setLastSync(0);
+ model.setChangedSyncPeriod(-1);
+ model.setFullSyncPeriod(-1);
+ model.setName("test-ldap");
+ model.setPriority(1);
+ model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
+ model.getConfig().addAll(ldapConfig);
+
+ ldapModel = appRealm.addComponentModel(model);
+ LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
+
+ // Delete all LDAP users and add some new for testing
+ LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
+ LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
+
+ // Remove the mapper for "username-cn" and create new mapper for fullName
+ ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "username-cn");
+ Assert.assertNotNull(mapperModel);
+ appRealm.removeComponent(mapperModel);
+
+ mapperModel = KeycloakModelUtils.createComponentModel("fullNameWritable", ldapModel.getId(), FullNameLDAPStorageMapperFactory.PROVIDER_ID, LDAPStorageMapper.class.getName(),
+ FullNameLDAPStorageMapper.LDAP_FULL_NAME_ATTRIBUTE, LDAPConstants.CN,
+ FullNameLDAPStorageMapper.READ_ONLY, "false",
+ FullNameLDAPStorageMapper.WRITE_ONLY, "true");
+ appRealm.addComponentModel(mapperModel);
+
+ appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
+ }
+ });
+
+
+ @ClassRule
+ public static TestRule chain = RuleChain
+ .outerRule(ldapRule)
+ .around(keycloakRule);
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ @WebResource
+ protected OAuthClient oauth;
+
+ @WebResource
+ protected WebDriver driver;
+
+ @WebResource
+ protected AppPage appPage;
+
+ @WebResource
+ protected RegisterPage registerPage;
+
+ @WebResource
+ protected LoginPage loginPage;
+
+ @WebResource
+ protected AccountUpdateProfilePage profilePage;
+
+ @WebResource
+ protected AccountPasswordPage changePasswordPage;
+
+
+
+// @Test
+// public void test01Sleep() throws Exception {
+// Thread.sleep(1000000);
+// }
+
+ @Test
+ public void test01_addUserWithoutFullName() {
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel john = session.users().addUser(appRealm, "johnkeycloak");
+ john.setEmail("johnkeycloak@email.cz");
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+
+ session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
+ Assert.assertNotNull(john.getFederationLink());
+ assertDnStartsWith(session, john, "cn=johnkeycloak");
+
+ session.users().removeUser(appRealm, john);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+
+ }
+
+
+ @Test
+ public void test02_registerUserWithFullName() {
+
+ loginPage.open();
+ loginPage.clickRegister();
+ registerPage.assertCurrent();
+
+ registerPage.register("Johny", "Anthony", "johnyanth@check.cz", "johnkeycloak", "Password1", "Password1");
+ Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmModel appRealm = session.realms().getRealmByName("test");
+ UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
+ assertUser(session, john, "johnkeycloak", "Johny", "Anthony", true, "cn=Johny Anthony");
+
+ session.users().removeUser(appRealm, john);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ @Test
+ public void test03_addUserWithFirstNameOnly() {
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel john = session.users().addUser(appRealm, "johnkeycloak");
+ john.setEmail("johnkeycloak@email.cz");
+ john.setFirstName("Johnyyy");
+ john.setEnabled(true);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+
+ session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
+ assertUser(session, john, "johnkeycloak", "Johnyyy", "", true, "cn=Johnyyy");
+
+ session.users().removeUser(appRealm, john);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ @Test
+ public void test04_addUserWithLastNameOnly() {
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel john = session.users().addUser(appRealm, "johnkeycloak");
+ john.setEmail("johnkeycloak@email.cz");
+ john.setLastName("Anthonyy");
+ john.setEnabled(true);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+
+ session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
+ assertUser(session, john, "johnkeycloak", "", "Anthonyy", true, "cn=Anthonyy");
+
+ session.users().removeUser(appRealm, john);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ @Test
+ public void test05_registerUserWithFullNameSpecialChars() {
+
+ loginPage.open();
+ loginPage.clickRegister();
+ registerPage.assertCurrent();
+
+ registerPage.register("Jož,o", "Baříč", "johnyanth@check.cz", "johnkeycloak", "Password1", "Password1");
+ Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmModel appRealm = session.realms().getRealmByName("test");
+ UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
+ assertUser(session, john, "johnkeycloak", "Jož,o", "Baříč", true, "cn=Jož\\,o Baříč");
+
+ session.users().removeUser(appRealm, john);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ @Test
+ public void test06_conflicts() {
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel john = session.users().addUser(appRealm, "existingkc");
+ john.setFirstName("John");
+ john.setLastName("Existing");
+ john.setEnabled(true);
+
+ UserModel john2 = session.users().addUser(appRealm, "existingkc1");
+ john2.setEnabled(true);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+
+ loginPage.open();
+ loginPage.clickRegister();
+ registerPage.assertCurrent();
+
+ registerPage.register("John", "Existing", "johnyanth@check.cz", "existingkc", "Password1", "Password1");
+ Assert.assertEquals("Username already exists.", registerPage.getError());
+
+ registerPage.register("John", "Existing", "johnyanth@check.cz", "existingkc2", "Password1", "Password1");
+ appPage.logout();
+
+ loginPage.open();
+ loginPage.clickRegister();
+ registerPage.assertCurrent();
+ registerPage.register("John", "Existing", "johnyanth2@check.cz", "existingkc3", "Password1", "Password1");
+
+ session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+ RealmModel appRealm = manager.getRealm("test");
+
+ UserModel existingKc = session.users().getUserByUsername("existingkc", appRealm);
+ assertUser(session, existingKc, "existingkc", "John", "Existing", true, "cn=John Existing");
+
+ UserModel existingKc1 = session.users().getUserByUsername("existingkc1", appRealm);
+ assertUser(session, existingKc1, "existingkc1", "", "", true, "cn=existingkc1");
+
+ UserModel existingKc2 = session.users().getUserByUsername("existingkc2", appRealm);
+ assertUser(session, existingKc2, "existingkc2", "John", "Existing", true, "cn=John Existing0");
+
+ UserModel existingKc3 = session.users().getUserByUsername("existingkc3", appRealm);
+ assertUser(session, existingKc3, "existingkc3", "John", "Existing", true, "cn=John Existing1");
+
+ session.users().removeUser(appRealm, existingKc);
+ session.users().removeUser(appRealm, existingKc1);
+ session.users().removeUser(appRealm, existingKc2);
+ session.users().removeUser(appRealm, existingKc3);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ private void assertUser(KeycloakSession session, UserModel user, String expectedUsername, String expectedFirstName, String expectedLastName, boolean expectedEnabled, String expectedDn) {
+ Assert.assertNotNull(user);
+ Assert.assertNotNull(user.getFederationLink());
+ Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
+ Assert.assertEquals(expectedUsername, user.getUsername());
+ Assert.assertEquals(expectedFirstName, user.getFirstName());
+ Assert.assertEquals(expectedLastName, user.getLastName());
+ Assert.assertEquals(expectedEnabled, user.isEnabled());
+ assertDnStartsWith(session, user, expectedDn);
+ }
+
+
+ private void assertDnStartsWith(KeycloakSession session, UserModel user, String expectedRDn) {
+ String usersDn = LDAPTestUtils.getLdapProvider(session, ldapModel).getLdapIdentityStore().getConfig().getUsersDn();
+ String userDN = user.getFirstAttribute(LDAPConstants.LDAP_ENTRY_DN);
+ Assert.assertTrue(userDN.equalsIgnoreCase(expectedRDn + "," + usersDn));
+ }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADMapperTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADMapperTest.java
new file mode 100644
index 0000000..1738892
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPMSADMapperTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.federation.storage.ldap;
+
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runners.MethodSorters;
+import org.keycloak.common.util.MultivaluedHashMap;
+import org.keycloak.component.ComponentModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.LDAPConstants;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.storage.UserStorageProvider;
+import org.keycloak.storage.UserStorageProviderModel;
+import org.keycloak.storage.ldap.LDAPStorageProvider;
+import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
+import org.keycloak.storage.ldap.idm.model.LDAPObject;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AccountPasswordPage;
+import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
+import org.keycloak.testsuite.pages.AppPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
+import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.LDAPRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class LDAPMSADMapperTest {
+
+ // Run this test just on MSAD
+ private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
+
+ String vendor = ldapConfig.get(LDAPConstants.VENDOR);
+
+ // TODO: This is skipped as it requires that MSAD server is set to not allow weak passwords (There needs to be pwdProperties=1 set on MSAD side).
+ // TODO: Currently we can't rely on it. See KEYCLOAK-4276
+ return true;
+ // return !(vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY));
+
+ });
+
+
+ private static ComponentModel ldapModel = null;
+
+
+ private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
+
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
+
+ MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
+ ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
+ ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
+ UserStorageProviderModel model = new UserStorageProviderModel();
+ model.setLastSync(0);
+ model.setChangedSyncPeriod(-1);
+ model.setFullSyncPeriod(-1);
+ model.setName("test-ldap");
+ model.setPriority(0);
+ model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
+ model.setConfig(ldapConfig);
+
+ ldapModel = appRealm.addComponentModel(model);
+ LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
+
+ // Delete all LDAP users and add some new for testing
+ LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
+ LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
+
+ LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
+ LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
+
+ appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
+ }
+ });
+
+ @ClassRule
+ public static TestRule chain = RuleChain
+ .outerRule(ldapRule)
+ .around(keycloakRule);
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ @WebResource
+ protected OAuthClient oauth;
+
+ @WebResource
+ protected WebDriver driver;
+
+ @WebResource
+ protected AppPage appPage;
+
+ @WebResource
+ protected RegisterPage registerPage;
+
+ @WebResource
+ protected LoginPage loginPage;
+
+ @WebResource
+ protected AccountUpdateProfilePage profilePage;
+
+ @WebResource
+ protected AccountPasswordPage changePasswordPage;
+
+ @WebResource
+ protected LoginPasswordUpdatePage passwordUpdatePage;
+
+
+ @Test
+ public void test01RegisterUserWithWeakPasswordFirst() {
+ loginPage.open();
+ loginPage.clickRegister();
+ registerPage.assertCurrent();
+
+ // Weak password. This will fail to update password to MSAD due to password policy.
+ registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "password", "password");
+
+ // Another weak password
+ passwordUpdatePage.assertCurrent();
+ passwordUpdatePage.changePassword("pass", "pass");
+ Assert.assertEquals("Invalid password: new password doesn't match password policies.", passwordUpdatePage.getError());
+
+ // Strong password. Successfully update password and being redirected to the app
+ passwordUpdatePage.changePassword("Password1", "Password1");
+ Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmModel appRealm = session.realms().getRealmByName("test");
+ UserModel user = session.users().getUserByUsername("registerUserSuccess2", appRealm);
+ Assert.assertNotNull(user);
+ Assert.assertNotNull(user.getFederationLink());
+ Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
+ Assert.assertEquals("registerusersuccess2", user.getUsername());
+ Assert.assertEquals("firstName", user.getFirstName());
+ Assert.assertEquals("lastName", user.getLastName());
+ Assert.assertTrue(user.isEnabled());
+ Assert.assertEquals(0, user.getRequiredActions().size());
+ } finally {
+ keycloakRule.stopSession(session, false);
+ }
+ }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java
index 4ea8ed7..1524981 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java
@@ -17,6 +17,7 @@
package org.keycloak.testsuite.federation.storage.ldap;
+import org.jboss.logging.Logger;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
@@ -74,6 +75,8 @@ import static org.junit.Assert.assertEquals;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class LDAPProvidersIntegrationTest {
+ private static final Logger log = Logger.getLogger(LDAPProvidersIntegrationTest.class);
+
private static LDAPRule ldapRule = new LDAPRule();
private static ComponentModel ldapModel = null;
@@ -388,6 +391,10 @@ public class LDAPProvidersIntegrationTest {
Assert.assertNotNull(user);
Assert.assertNotNull(user.getFederationLink());
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
+ Assert.assertEquals("registerusersuccess2", user.getUsername());
+ Assert.assertEquals("firstName", user.getFirstName());
+ Assert.assertEquals("lastName", user.getLastName());
+ Assert.assertTrue(user.isEnabled());
} finally {
keycloakRule.stopSession(session, false);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSpecialCharsTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSpecialCharsTest.java
index 4b3ee71..8d31030 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSpecialCharsTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPSpecialCharsTest.java
@@ -17,16 +17,13 @@
package org.keycloak.testsuite.federation.storage.ldap;
-import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
import org.junit.After;
-import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Rule;
@@ -40,11 +37,15 @@ import org.keycloak.component.ComponentModel;
import org.keycloak.models.Constants;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.storage.ldap.LDAPStorageProvider;
+import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
+import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AppPage;
@@ -66,7 +67,16 @@ import static org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class LDAPSpecialCharsTest {
- private static LDAPRule ldapRule = new LDAPRule();
+
+ // Skip this test for MSAD with sAMAccountName as it is not allowed to use specialCharacters in sAMAccountName attribute
+ private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
+
+ String vendor = ldapConfig.get(LDAPConstants.VENDOR);
+ String usernameAttr = ldapConfig.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
+
+ return (vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY) && usernameAttr.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME));
+
+ });
static ComponentModel ldapModel = null;
static String descriptionAttrName = null;
@@ -75,9 +85,18 @@ public class LDAPSpecialCharsTest {
private static KeycloakRule keycloakRule = new KeycloakRule(new LDAPGroupMapperTest.GroupTestKeycloakSetup(ldapRule) {
@Override
- protected void postSetup() {
+ protected void postSetup(RealmModel appRealm, LDAPStorageProvider ldapProvider) {
LDAPSpecialCharsTest.ldapModel = this.ldapModel;
LDAPSpecialCharsTest.descriptionAttrName = this.descriptionAttrName;
+
+ LDAPObject groupSpecialCharacters = LDAPTestUtils.createLDAPGroup(session, appRealm, ldapModel, "group-spec,ia*l_characžter)s", descriptionAttrName, "group-special-characters");
+
+ // Resync LDAP groups to Keycloak DB
+ ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "groupsMapper");
+ new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(appRealm);
+
+ LDAPObject james2 = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "jamees,key*cložak)ppp", "James2", "Brown2", "james2@email.org", null, "89102");
+ LDAPTestUtils.updateLDAPPassword(ldapProvider, james2, "Password1");
}
});
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
index c4e2a36..d0c770e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
@@ -117,8 +117,12 @@ public class SamlAdapterTest {
testStrategy.testSavedPostRequest();
}
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
public void testMetadataPostSignedLoginLogout() throws Exception {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
index 9589fe9..91074e3 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
@@ -20,10 +20,12 @@ package org.keycloak.testsuite.keycloaksaml;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.rules.ExternalResource;
+
import org.keycloak.adapters.saml.SamlAuthenticationError;
import org.keycloak.adapters.saml.SamlPrincipal;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.common.util.*;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
@@ -38,9 +40,8 @@ import org.keycloak.protocol.saml.mappers.RoleNameMapper;
import org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.saml.BaseSAML2BindingBuilder;
-import org.keycloak.saml.SAML2ErrorResponseBuilder;
-import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.*;
+import org.keycloak.saml.common.constants.*;
import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.KeycloakServer;
@@ -51,6 +52,7 @@ import org.keycloak.testsuite.rule.ErrorServlet;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
+
import org.openqa.selenium.WebDriver;
import org.w3c.dom.Document;
@@ -61,10 +63,11 @@ import javax.ws.rs.core.Form;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.URI;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+import java.util.Base64;
+import java.util.logging.*;
import static org.junit.Assert.assertEquals;
@@ -77,6 +80,24 @@ public class SamlAdapterTestStrategy extends ExternalResource {
protected String APP_SERVER_BASE_URL = "http://localhost:8081";
protected AbstractKeycloakRule keycloakRule;
+ private static final String REALM_PRIVATE_KEY_STR = "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=";
+ private static PrivateKey REALM_PRIVATE_KEY;
+ private static final String REALM_PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB";
+ private static PublicKey REALM_PUBLIC_KEY;
+
+ static {
+ try {
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ byte[] encoded = Base64.getDecoder().decode(REALM_PUBLIC_KEY_STR);
+ REALM_PUBLIC_KEY = (PublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
+
+ encoded = Base64.getDecoder().decode(REALM_PRIVATE_KEY_STR);
+ REALM_PRIVATE_KEY = (PrivateKey) kf.generatePrivate(new PKCS8EncodedKeySpec(encoded));
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
+ Logger.getLogger(SamlAdapterTestStrategy.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
public SamlAdapterTestStrategy(String AUTH_SERVER_URL, String APP_SERVER_BASE_URL, AbstractKeycloakRule keycloakRule) {
this.AUTH_SERVER_URL = AUTH_SERVER_URL;
this.APP_SERVER_BASE_URL = APP_SERVER_BASE_URL;
@@ -173,7 +194,7 @@ public class SamlAdapterTestStrategy extends ExternalResource {
- public void testErrorHandling() throws Exception {
+ public void testErrorHandlingUnsigned() throws Exception {
ErrorServlet.authError = null;
Client client = ClientBuilder.newClient();
// make sure
@@ -194,6 +215,36 @@ public class SamlAdapterTestStrategy extends ExternalResource {
client.close();
Assert.assertNotNull(ErrorServlet.authError);
SamlAuthenticationError error = (SamlAuthenticationError)ErrorServlet.authError;
+ Assert.assertEquals(SamlAuthenticationError.Reason.INVALID_SIGNATURE, error.getReason());
+ Assert.assertNotNull(error.getStatus());
+ ErrorServlet.authError = null;
+
+ }
+
+ public void testErrorHandlingSigned() throws Exception {
+ ErrorServlet.authError = null;
+ Client client = ClientBuilder.newClient();
+ // make sure
+ Response response = client.target(APP_SERVER_BASE_URL + "/employee-sig/").request().get();
+ response.close();
+ SAML2ErrorResponseBuilder builder = new SAML2ErrorResponseBuilder()
+ .destination(APP_SERVER_BASE_URL + "/employee-sig/saml")
+ .issuer(AUTH_SERVER_URL + "/realms/demo")
+ .status(JBossSAMLURIConstants.STATUS_REQUEST_DENIED.get());
+ BaseSAML2BindingBuilder binding = new BaseSAML2BindingBuilder()
+ .relayState(null)
+ .signatureAlgorithm(SignatureAlgorithm.RSA_SHA256)
+ .signWith(KeyUtils.createKeyId(REALM_PRIVATE_KEY), REALM_PRIVATE_KEY, REALM_PUBLIC_KEY)
+ .signDocument();
+ Document document = builder.buildDocument();
+ URI uri = binding.generateRedirectUri(GeneralConstants.SAML_RESPONSE_KEY, APP_SERVER_BASE_URL + "/employee-sig/saml", document);
+ response = client.target(uri).request().get();
+ String errorPage = response.readEntity(String.class);
+ response.close();
+ Assert.assertTrue(errorPage.contains("Error Page"));
+ client.close();
+ Assert.assertNotNull(ErrorServlet.authError);
+ SamlAuthenticationError error = (SamlAuthenticationError)ErrorServlet.authError;
Assert.assertEquals(SamlAuthenticationError.Reason.ERROR_STATUS, error.getReason());
Assert.assertNotNull(error.getStatus());
ErrorServlet.authError = null;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java
index acc27a6..b3cdec4 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/samlfilter/SamlAdapterTest.java
@@ -128,7 +128,7 @@ public class SamlAdapterTest {
@Test
public void testPostPassiveLoginLogout() {
- testStrategy.testPostPassiveLoginLogout(false);
+ testStrategy.testPostPassiveLoginLogout(true);
}
@Test
testsuite/integration-arquillian/pom.xml 33(+27 -6)
diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml
index f563887..a5cd163 100644
--- a/testsuite/integration-arquillian/pom.xml
+++ b/testsuite/integration-arquillian/pom.xml
@@ -50,8 +50,9 @@
<undertow-embedded.version>1.0.0.Alpha2</undertow-embedded.version>
<!--migration properties-->
- <migration.project.version>2.2.1.Final</migration.project.version>
- <migration.product.version>1.9.8.Final</migration.product.version>
+ <migration.70.version>1.9.8.Final</migration.70.version>
+ <migration.70.authz.version>2.2.1.Final</migration.70.authz.version>
+ <!--<migration.71.version>2.5.1.Final</migration.71.version>-->
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
@@ -135,9 +136,9 @@
<profiles>
<profile>
- <id>test-project-migration</id>
+ <id>test-70-migration</id>
<properties>
- <migrated.auth.server.version>${migration.project.version}</migrated.auth.server.version>
+ <migrated.auth.server.version>${migration.70.version}</migrated.auth.server.version>
</properties>
<build>
<pluginManagement>
@@ -155,9 +156,9 @@
</build>
</profile>
<profile>
- <id>test-product-migration</id>
+ <id>test-70-authz-migration</id>
<properties>
- <migrated.auth.server.version>${migration.product.version}</migrated.auth.server.version>
+ <migrated.auth.server.version>${migration.70.authz.version}</migrated.auth.server.version>
</properties>
<build>
<pluginManagement>
@@ -174,6 +175,26 @@
</pluginManagement>
</build>
</profile>
+<!-- <profile>
+ <id>test-71-migration</id>
+ <properties>
+ <migrated.auth.server.version>${migration.71.version}</migrated.auth.server.version>
+ </properties>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <migrated.auth.server.version>${migrated.auth.server.version}</migrated.auth.server.version>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ </profile>-->
</profiles>
</project>
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java
index b8b244d..5110b32 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/ConsentPage.java
@@ -28,10 +28,17 @@ public class ConsentPage extends AbstractPage {
@FindBy(id = "kc-login")
private WebElement submitButton;
+ @FindBy(id = "kc-cancel")
+ private WebElement cancelButton;
+
public void confirm() {
submitButton.click();
}
+ public void cancel() {
+ cancelButton.click();
+ }
+
@Override
public boolean isCurrent() {
return driver.getTitle().equalsIgnoreCase("grant access");
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 97e3c84..4c408ba 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -864,7 +864,7 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
Assert.assertTrue(applicationsPage.isCurrent());
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
- Assert.assertThat(apps.keySet(), containsInAnyOrder("Account", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App"));
+ Assert.assertThat(apps.keySet(), containsInAnyOrder("Account", "test-app", "test-app-scope", "third-party", "test-app-authz", "My Named Test App", "Test App Named - ${client_account}"));
AccountApplicationsPage.AppEntry accountEntry = apps.get("Account");
Assert.assertEquals(2, accountEntry.getRolesAvailable().size());
@@ -951,7 +951,20 @@ public class AccountTest extends AbstractTestRealmKeycloakTest {
// When a client has a name provided, the name should be available to the back link
Assert.assertEquals("Back to " + namedClient.getName(), profilePage.getBackToApplicationLinkText());
Assert.assertEquals(namedClient.getBaseUrl(), profilePage.getBackToApplicationLinkHref());
-
+
+ foundClients = testRealm.clients().findByClientId("var-named-test-app");
+ if (foundClients.isEmpty()) {
+ Assert.fail("Unable to find var-named-test-app");
+ }
+ namedClient = foundClients.get(0);
+
+ driver.navigate().to(profilePage.getPath() + "?referrer=" + namedClient.getClientId());
+ Assert.assertTrue(profilePage.isCurrent());
+ // When a client has a name provided as a variable, the name should be resolved using a localized bundle and available to the back link
+ Assert.assertEquals("Back to Test App Named - Account", profilePage.getBackToApplicationLinkText());
+ Assert.assertEquals(namedClient.getBaseUrl(), profilePage.getBackToApplicationLinkHref());
+
+
foundClients = testRealm.clients().findByClientId("test-app");
if (foundClients.isEmpty()) {
Assert.fail("Unable to find test-app");
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java
index 217a4e7..c2c628d 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBaseBrokerTest.java
@@ -20,10 +20,7 @@ package org.keycloak.testsuite.broker;
import java.util.List;
import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.Retry;
@@ -35,8 +32,6 @@ import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
import org.openqa.selenium.TimeoutException;
-import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
-import static org.keycloak.testsuite.admin.ApiUtil.resetUserPassword;
import static org.keycloak.testsuite.broker.BrokerTestTools.encodeUrl;
import static org.keycloak.testsuite.broker.BrokerTestTools.waitForPage;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
index 8950d1b..6f3314f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
@@ -2,28 +2,31 @@ package org.keycloak.testsuite.broker;
import org.junit.Before;
import org.junit.Test;
+
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.Assert;
-import org.keycloak.testsuite.util.RealmBuilder;
+import org.keycloak.testsuite.pages.ConsentPage;
+import org.keycloak.testsuite.util.*;
import org.openqa.selenium.TimeoutException;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
import static org.keycloak.testsuite.admin.ApiUtil.resetUserPassword;
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_EMAIL;
-import static org.keycloak.testsuite.broker.BrokerTestTools.*;
import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl;
-import org.keycloak.testsuite.util.MailServer;
-import org.keycloak.testsuite.util.MailServerConfiguration;
-import org.keycloak.testsuite.util.UserBuilder;
+
+import org.jboss.arquillian.graphene.page.Page;
+
+import static org.keycloak.testsuite.broker.BrokerTestTools.*;
public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
@@ -256,6 +259,44 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
assertEquals("Account is disabled, contact admin.", errorPage.getError());
}
+ @Page
+ ConsentPage consentPage;
+
+ // KEYCLOAK-4181
+ @Test
+ public void loginWithExistingUserWithErrorFromProviderIdP() {
+ ClientRepresentation client = adminClient.realm(bc.providerRealmName())
+ .clients()
+ .findByClientId(bc.getIDPClientIdInProviderRealm(suiteContext))
+ .get(0);
+
+ adminClient.realm(bc.providerRealmName())
+ .clients()
+ .get(client.getId())
+ .update(ClientBuilder.edit(client).consentRequired(true).build());
+
+ driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
+
+ log.debug("Clicking social " + bc.getIDPAlias());
+ accountLoginPage.clickSocial(bc.getIDPAlias());
+
+ waitForPage(driver, "log in to");
+
+ Assert.assertTrue("Driver should be on the provider realm page right now",
+ driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
+
+ log.debug("Logging in");
+ accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
+
+ driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.MINUTES);
+
+ waitForPage(driver, "grant access");
+ consentPage.cancel();
+
+ waitForPage(driver, "log in to");
+ }
+
+
protected void testSingleLogout() {
log.debug("Testing single log out");
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerConfiguration.java
index 0e00a70..5605cf6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerConfiguration.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/BrokerConfiguration.java
@@ -43,6 +43,11 @@ public interface BrokerConfiguration {
String consumerRealmName();
/**
+ * @return Client ID of the identity provider as set in provider realm.
+ */
+ String getIDPClientIdInProviderRealm(SuiteContext suiteContext);
+
+ /**
* @return User login name of the brokered user
*/
String getUserLogin();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java
index aa3e56e..61664a9 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java
@@ -50,6 +50,7 @@ public class KcOidcBrokerConfiguration implements BrokerConfiguration {
public List<ClientRepresentation> createProviderClients(SuiteContext suiteContext) {
ClientRepresentation client = new ClientRepresentation();
client.setId(CLIENT_ID);
+ client.setClientId(getIDPClientIdInProviderRealm(suiteContext));
client.setName(CLIENT_ID);
client.setSecret(CLIENT_SECRET);
client.setEnabled(true);
@@ -124,6 +125,11 @@ public class KcOidcBrokerConfiguration implements BrokerConfiguration {
}
@Override
+ public String getIDPClientIdInProviderRealm(SuiteContext suiteContext) {
+ return CLIENT_ID;
+ }
+
+ @Override
public String getUserPassword() {
return USER_PASSWORD;
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOIDCBrokerWithSignatureTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOIDCBrokerWithSignatureTest.java
index 6bc60b1..e7d8d44 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOIDCBrokerWithSignatureTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOIDCBrokerWithSignatureTest.java
@@ -211,6 +211,23 @@ public class KcOIDCBrokerWithSignatureTest extends AbstractBaseBrokerTest {
// Set key id to a valid one
cfg.setPublicKeySignatureVerifierKeyId(expectedKeyId);
updateIdentityProvider(idpRep);
+ logInAsUserInIDP();
+ assertLoggedInAccountManagement();
+ logoutFromRealm(bc.consumerRealmName());
+
+ // Set key id to empty
+ cfg.setPublicKeySignatureVerifierKeyId("");
+ updateIdentityProvider(idpRep);
+ logInAsUserInIDP();
+ assertLoggedInAccountManagement();
+ logoutFromRealm(bc.consumerRealmName());
+
+ // Unset key id
+ cfg.setPublicKeySignatureVerifierKeyId(null);
+ updateIdentityProvider(idpRep);
+ logInAsUserInIDP();
+ assertLoggedInAccountManagement();
+ logoutFromRealm(bc.consumerRealmName());
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java
index 7da71ad..e5f5b8d 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java
@@ -54,7 +54,7 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
public List<ClientRepresentation> createProviderClients(SuiteContext suiteContext) {
ClientRepresentation client = new ClientRepresentation();
- client.setClientId(getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME);
+ client.setClientId(getIDPClientIdInProviderRealm(suiteContext));
client.setEnabled(true);
client.setProtocol(IDP_SAML_PROVIDER_ID);
client.setRedirectUris(Collections.singletonList(
@@ -157,6 +157,11 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
}
@Override
+ public String getIDPClientIdInProviderRealm(SuiteContext suiteContext) {
+ return getAuthRoot(suiteContext) + "/auth/realms/" + consumerRealmName();
+ }
+
+ @Override
public String getUserLogin() {
return USER_LOGIN;
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java
index cd315f3..b4825cd 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java
@@ -15,8 +15,6 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
public static class KcSamlSignedBrokerConfiguration extends KcSamlBrokerConfiguration {
- public static final KcSamlSignedBrokerConfiguration INSTANCE = new KcSamlSignedBrokerConfiguration();
-
@Override
public RealmRepresentation createProviderRealm() {
RealmRepresentation realm = super.createProviderRealm();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
index e94edce..4cf3904 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
@@ -17,7 +17,6 @@
package org.keycloak.testsuite.composites;
import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
@@ -28,6 +27,7 @@ import org.keycloak.common.enums.SslRequired;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.util.ClientBuilder;
@@ -345,4 +345,22 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
Assert.assertEquals(200, refreshResponse.getStatusCode());
}
+
+ // KEYCLOAK-4274
+ @Test
+ public void testRecursiveComposites() throws Exception {
+ // This will create recursive composite mappings between "REALM_COMPOSITE_1" and "REALM_ROLE_1"
+ RoleRepresentation realmComposite1 = testRealm().roles().get("REALM_COMPOSITE_1").toRepresentation();
+ testRealm().roles().get("REALM_ROLE_1").addComposites(Collections.singletonList(realmComposite1));
+
+ UserResource userResource = ApiUtil.findUserByUsernameId(testRealm(), "REALM_COMPOSITE_1_USER");
+ List<RoleRepresentation> realmRoles = userResource.roles().realmLevel().listEffective();
+ Assert.assertNames(realmRoles, "REALM_COMPOSITE_1", "REALM_ROLE_1");
+
+ userResource = ApiUtil.findUserByUsernameId(testRealm(), "REALM_ROLE_1_USER");
+ realmRoles = userResource.roles().realmLevel().listEffective();
+ Assert.assertNames(realmRoles, "REALM_COMPOSITE_1", "REALM_ROLE_1");
+
+ }
+
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
index 5d5b343..fa30e65 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
@@ -179,6 +179,9 @@ public class ExportImportTest extends AbstractExportImportTest {
List<ComponentRepresentation> components = adminClient.realm("test").components().query();
KeysMetadataRepresentation keyMetadata = adminClient.realm("test").keys().getKeyMetadata();
+ String sampleRealmRoleId = adminClient.realm("test").roles().get("sample-realm-role").toRepresentation().getId();
+ String testAppId = adminClient.realm("test").clients().findByClientId("test-app").get(0).getId();
+ String sampleClientRoleId = adminClient.realm("test").clients().get(testAppId).roles().get("sample-client-role").toRepresentation().getId();
// Delete some realm (and some data in admin realm)
adminClient.realm("test").remove();
@@ -208,6 +211,12 @@ public class ExportImportTest extends AbstractExportImportTest {
KeysMetadataRepresentation keyMetadataImported = adminClient.realm("test").keys().getKeyMetadata();
assertEquals(keyMetadata.getActive(), keyMetadataImported.getActive());
+
+ String importedSampleRealmRoleId = adminClient.realm("test").roles().get("sample-realm-role").toRepresentation().getId();
+ assertEquals(sampleRealmRoleId, importedSampleRealmRoleId);
+
+ String importedSampleClientRoleId = adminClient.realm("test").clients().get(testAppId).roles().get("sample-client-role").toRepresentation().getId();
+ assertEquals(sampleClientRoleId, importedSampleClientRoleId);
}
private void assertAuthenticated(String realmName, String username, String password) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/LegacyImportTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/LegacyImportTest.java
index e7ec574..3dcffcd 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/LegacyImportTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/LegacyImportTest.java
@@ -38,7 +38,6 @@ import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Set;
-import static org.junit.Assert.assertNotNull;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.exportimport.Strategy;
import static org.keycloak.testsuite.Assert.assertNames;
@@ -62,25 +61,8 @@ public class LegacyImportTest extends AbstractExportImportTest {
}
@Test
- public void importPreviousProject() throws Exception {
-
- String projectVersion = System.getProperty("migration.project.version");
- assertNotNull(projectVersion);
-
- testLegacyImport(projectVersion);
- }
-
- @Test
- public void importPreviousProduct() throws Exception {
-
- String productVersion = System.getProperty("migration.product.version");
- assertNotNull(productVersion);
-
- testLegacyImport(productVersion);
- }
-
- private void testLegacyImport(String version) {
- String file = "/migration-test/migration-realm-" + version + ".json";
+ public void testLegacyImport(String version) {
+ String file = "/migration-test/migration-realm-1.9.8.Final.json";
URL url = LegacyImportTest.class.getResource(file);
String targetFilePath = new File(url.getFile()).getAbsolutePath();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/AccountPageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/AccountPageTest.java
index 237b5e6..cc72876 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/AccountPageTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/AccountPageTest.java
@@ -19,9 +19,13 @@ package org.keycloak.testsuite.i18n;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
import org.junit.Test;
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.LoginPage;
+import java.util.List;
+
/**
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
@@ -49,4 +53,25 @@ public class AccountPageTest extends AbstractI18NTest {
Assert.assertEquals("English", accountUpdateProfilePage.getLanguageDropdownText());
accountUpdateProfilePage.logout();
}
+
+ @Test
+ public void testLocalizedReferrerLinkContent() {
+ RealmResource testRealm = testRealm();
+ List<ClientRepresentation> foundClients = testRealm.clients().findByClientId("var-named-test-app");
+ if (foundClients.isEmpty()) {
+ Assert.fail("Unable to find var-named-test-app");
+ }
+ ClientRepresentation namedClient = foundClients.get(0);
+
+ driver.navigate().to(accountUpdateProfilePage.getPath() + "?referrer=" + namedClient.getClientId());
+ loginPage.login("test-user@localhost", "password");
+ Assert.assertTrue(accountUpdateProfilePage.isCurrent());
+
+ accountUpdateProfilePage.openLanguage("Deutsch");
+ Assert.assertEquals("Deutsch", accountUpdateProfilePage.getLanguageDropdownText());
+
+ // When a client has a name provided as a variable, the name should be resolved using a localized bundle and available to the back link
+ Assert.assertEquals("Zur\u00FCck zu Test App Named - Konto", accountUpdateProfilePage.getBackToApplicationLinkText());
+ Assert.assertEquals(namedClient.getBaseUrl(), accountUpdateProfilePage.getBackToApplicationLinkHref());
+ }
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java
index 2e45ccb..7c8041b 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java
@@ -17,38 +17,37 @@
package org.keycloak.testsuite.migration;
import java.util.HashSet;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.common.constants.KerberosConstants;
-import org.keycloak.component.PrioritizedComponentModel;
-import org.keycloak.keys.KeyProvider;
-import org.keycloak.models.LDAPConstants;
-import org.keycloak.representations.idm.ComponentRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.authorization.PolicyRepresentation;
-import org.keycloak.storage.UserStorageProvider;
-import org.keycloak.testsuite.AbstractKeycloakTest;
-import org.keycloak.testsuite.arquillian.migration.Migration;
-
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
-
+import javax.ws.rs.NotFoundException;
import org.junit.Before;
+import org.junit.Test;
import org.keycloak.admin.client.resource.ClientResource;
+import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleResource;
+import org.keycloak.common.constants.KerberosConstants;
+import org.keycloak.component.PrioritizedComponentModel;
+import org.keycloak.keys.KeyProvider;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.Constants;
+import org.keycloak.models.LDAPConstants;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ClientTemplateRepresentation;
+import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.authorization.PolicyRepresentation;
+import org.keycloak.storage.UserStorageProvider;
+import org.keycloak.testsuite.AbstractKeycloakTest;
+import org.keycloak.testsuite.arquillian.migration.Migration;
import static org.keycloak.testsuite.Assert.assertEquals;
import static org.keycloak.testsuite.Assert.assertFalse;
@@ -64,7 +63,7 @@ public class MigrationTest extends AbstractKeycloakTest {
public static final String MIGRATION = "Migration";
public static final String MIGRATION2 = "Migration2";
- public static final String MIGRATION3 = "authorization";
+
private RealmResource migrationRealm;
private RealmResource migrationRealm2;
private RealmResource migrationRealm3;
@@ -79,11 +78,21 @@ public class MigrationTest extends AbstractKeycloakTest {
public void beforeMigrationTest() {
migrationRealm = adminClient.realms().realm(MIGRATION);
migrationRealm2 = adminClient.realms().realm(MIGRATION2);
- migrationRealm3 = adminClient.realms().realm(MIGRATION3);
+ migrationRealm3 = adminClient.realms().realm("authorization");
+
masterRealm = adminClient.realms().realm(MASTER);
- //add migration realm to testRealmReps to make the migration removed after test
- testRealmReps.add(adminClient.realms().realm(MIGRATION).toRepresentation());
+ //add migration realms to testRealmReps to make them removed after test
+ addTestRealmToTestRealmReps(migrationRealm);
+ addTestRealmToTestRealmReps(migrationRealm2);
+ addTestRealmToTestRealmReps(migrationRealm3);
+ }
+
+ private void addTestRealmToTestRealmReps(RealmResource realm) {
+ try {
+ testRealmReps.add(realm.toRepresentation());
+ } catch (NotFoundException ex) {
+ }
}
@Test
@@ -95,18 +104,16 @@ public class MigrationTest extends AbstractKeycloakTest {
testMigrationTo2_2_0();
testMigrationTo2_3_0();
testMigrationTo2_5_0();
- testLdapKerberosMigration_2_5_0();
}
@Test
@Migration(versionFrom = "2.2.1.Final")
- public void migration2_2_1Test() {
- testMigrationTo2_3_0();
- testMigrationTo2_5_0();
- testMigrationTo2_5_1();
+ public void migrationInAuthorizationServicesTest() {
+ testDroolsToRulesPolicyTypeMigration();
}
private void testMigratedData() {
+ log.info("testing migrated data");
//master realm
assertNames(masterRealm.roles().list(), "offline_access", "uma_authorization", "create-realm", "master-test-realm-role", "admin");
assertNames(masterRealm.clients().findAll(), "admin-cli", "security-admin-console", "broker", "account",
@@ -155,7 +162,15 @@ public class MigrationTest extends AbstractKeycloakTest {
testExtractRealmKeys(masterRealm, migrationRealm);
}
+ private void testMigrationTo2_5_0() {
+ testLdapKerberosMigration_2_5_0();
+
+ //https://github.com/keycloak/keycloak/pull/3630
+ testDuplicateEmailSupport(masterRealm, migrationRealm);
+ }
+
private void testExtractRealmKeys(RealmResource masterRealm, RealmResource migrationRealm) {
+ log.info("testing extract realm keys");
String expectedMasterRealmKey = "MIIEowIBAAKCAQEAiU54OXoCbHy0L0gHn1yasctcnKHRU1pHFIJnWvaI7rClJydet9dDJaiYXOxMKseiBm3eYznfN3cPyU8udYmRnMuKjiocZ77LT2IEttAjXb6Ggazx7loriFHRy0IOJeX4KxXhAPWmxqa3mkFNfLBEvFqVaBgUDHQ60cmnPvNSHYudBTW9K80s8nvmP2pso7HTwWJ1+Xatj1Ey/gTmB3CXlyqBegGWC9TeuErEYpYhdh+11TVWasgMBZyUCtL3NRPaBuhaPg1LpW8lWGk05nS+YM6dvTk3Mppv+z2RygEpxyO09oT3b4G+Zfwit1STqn0AvDTGzINdoKcNtFScV0j8TwIDAQABAoIBAHcbPKsPLZ8SJfOF1iblW8OzFulAbaaSf2pJHIMJrQrw7LKkMkPjVXoLX+/rgr7xYZmWIP2OLBWfEHCeYTzQUyHiZpSf7vgHx7Fa45/5uVQOe/ttHIiYa37bCtP4vvEdJkOpvP7qGPvljwsebqsk9Ns28LfVez66bHOjK5Mt2yOIulbTeEs7ch//h39YwKJv96vc+CHbV2O6qoOxZessO6y+287cOBvbFXmS2GaGle5Nx/EwncBNS4b7czoetmm70+9ht3yX+kxaP311YUT31KQjuaJt275kOiKsrXr27PvgO++bsIyGuSzqyS7G7fmxF2zUyphEqEpalyDGMKMnrAECgYEA1fCgFox03rPDjm0MhW/ThoS2Ld27sbWQ6reS+PBMdUTJZVZIU1D2//h6VXDnlddhk6avKjA4smdy1aDKzmjz3pt9AKn+kgkXqtTC2fD3wp+fC9hND0z+rQPGe/Gk7ZUnTdsqnfyowxr+woIgzdnRukOUrG+xQiP3RUUT7tt6NQECgYEApEz2xvgqMm+9/f/YxjLdsFUfLqc4WlafB863stYEVqlCYy5ujyo0VQ0ahKSKJkLDnf52+aMUqPOpwaGePpu3O6VkvpcKfPY2MUlZW7/6Sa9et9hxNkdTS7Gui2d1ELpaCBe1Bc62sk8EA01iHXE1PpvyUqDWrhNh+NrDICA9oU8CgYBgGDYACtTP11TmW2r9YK5VRLUDww30k4ZlN1GnyV++aMhBYVEZQ0u+y+A/EnijIFwu0vbo70H4OGknNZMCxbeMbLDoJHM5KyZbUDe5ZvgSjloFGwH59m6KTiDQOUkIgi9mVCQ/VGaFRFHcElEjxUvj60kTbxPijn8ZuR5r8l9hAQKBgQCQ9jL5pHWeoIayN20smi6M6N2lTPbkhe60dcgQatHTIG2pkosLl8IqlHAkPgSB84AiwyR351JQKwRJCm7TcJI/dxMnMZ6YWKfB3qSP1hdfsfJRJQ/mQxIUBAYrizF3e+P5peka4aLCOgMhYsJBlePThMZN7wja99EGPwXQL4IQ8wKBgB8Nis1lQK6Z30GCp9u4dYleGfEP71Lwqvk/eJb89/uz0fjF9CTpJMULFc+nA5u4yHP3LFnRg3zCU6aEwfwUyk4GH9lWGV/qIAisQtgrCEraVe4qxz0DVE59C7qjO26IhU2U66TEzPAqvQ3zqey+woDn/cz/JMWK1vpcSk+TKn3K";
String expectedMigrationRealmKey = "MIIEpAIBAAKCAQEApt6gCllWkVTZ7fy/oRIx6Bxjt9x3eKKyKGFXvN4iaafrNqpYU9lcqPngWJ9DyXGqUf8RpjPaQWiLWLxjw3xGBqLk2E1/Frb9e/dy8rj//fHGq6bujN1iguzyFwxPGT5Asd7jflRI3qU04M8JE52PArqPhGL2Fn+FiSK5SWRIGm+hVL7Ck/E/tVxM25sFG1/UTQqvrROm4q76TmP8FsyZaTLVf7cCwW2QPIX0N5HTVb3QbBb5KIsk4kKmk/g7uUxS9r42tu533LISzRr5CTyWZAL2XFRuF2RrKdE8gwqkEubw6sDmB2mE0EoPdY1DUhBQgVP/5rwJrCtTsUBR2xdEYQIDAQABAoIBAFbbsNBSOlZBpYJUOmcb8nBQPrOYhXN8tGGCccn0klMOvcdhmcJjdPDbyCQ5Gm7DxJUTwNsTSHsdcNMKlJ9Pk5+msJnKlOl87KrXXbTsCQvlCrWUmb0nCzz9GvJWTOHl3oT3cND0DE4gDksqWR4luCgCdevCGzgQvrBoK6wBD+r578uEW3iw10hnJ0+wnGiw8IvPzE1a9xbY4HD8/QrYdaLxuLb/aC1PDuzrz0cOjnvPkrws5JrbUSnbFygJiOv1z4l2Q00uGIxlHtXdwQBnTZZjVi4vOec2BYSHffgwDYEZIglw1mnrV7y0N1nnPbtJK/cegIkXoBQHXm8Q99TrWMUCgYEA9au86qcwrXZZg5H4BpR5cpy0MSkcKDbA1aRL1cAyTCqJxsczlAtLhFADF+NhnlXj4y7gwDEYWrz064nF73I+ZGicvCiyOy+tCTugTyTGS+XR948ElDMS6PCUUXsotS3dKa0b3c9wd2mxeddTjq/ArfgEVZJ6fE1KtjLt9dtfA+8CgYEAreK3JsvjR5b/Xct28TghYUU7Qnasombb/shqqy8FOMjYUr5OUm/OjNIgoCqhOlE8oQDJ4dOZofNSa7tL+oM8Gmbal+E3fRzxnx/9/EC4QV6sVaPLTIyk7EPfKTcZuzH7+BNZtAziTxJw9d6YJQRbkpg92EZIEoR8iDj2Xs5xrK8CgYEAwMVWwwYX8zT3vn7ukTM2LRH7bsvkVUXJgJqgCwT6Mrv6SmkK9vL5+cPS+Y6pjdW1sRGauBSOGL1Grf/4ug/6F03jFt4UJM8fRyxreU7Q7sNSQ6AMpsGA6BnHODycz7ZCYa59PErG5FyiL4of/cm5Nolz1TXQOPNpWZiTEqVlZC8CgYA4YPbjVF4nuxSnU64H/hwMjsbtAM9uhI016cN0J3W4+J3zDhMU9X1x+Tts0wWdg/N1fGz4lIQOl3cUyRCUc/KL2OdtMS+tmDHbVyMho9ZaE5kq10W2Vy+uDz+O/HeSU12QDK4cC8Vgv+jyPy7zaZtLR6NduUPrBRvfiyCOkr8WrwKBgQCY0h4RCdNFhr0KKLLmJipAtV8wBCGcg1jY1KoWKQswbcykfBKwHbF6EooVqkRW0ITjWB7ZZCf8TnSUxe0NXCUAkVBrhzS4DScgtoSZYOOUaSHgOxpfwgnQ3oYotKi98Yg3IsaLs1j4RuPG5Sp1z6o+ELP1uvr8azyn9YlLa+523Q==";
@@ -180,18 +195,8 @@ public class MigrationTest extends AbstractKeycloakTest {
assertEquals(1, components.size());
}
- private void testMigrationTo2_5_0() {
- //TODO org.keycloak.migration.migrators.MigrateTo2_5_0
-
- //https://github.com/keycloak/keycloak/pull/3630
- testDuplicateEmailSupport(masterRealm, migrationRealm);
- }
-
- private void testMigrationTo2_5_1() {
- testDroolsToRulesPolicyTypeMigration();
- }
-
private void testLdapKerberosMigration_2_5_0() {
+ log.info("testing ldap kerberos migration");
RealmRepresentation realmRep = migrationRealm2.toRepresentation();
List<ComponentRepresentation> components = migrationRealm2.components().query(realmRep.getId(), UserStorageProvider.class.getName());
assertEquals(2, components.size());
@@ -226,6 +231,7 @@ public class MigrationTest extends AbstractKeycloakTest {
}
private void testDroolsToRulesPolicyTypeMigration() {
+ log.info("testing drools to rules in authorization services");
List<ClientRepresentation> client = migrationRealm3.clients().findByClientId("photoz-restful-api");
assertEquals(1, client.size());
@@ -240,6 +246,7 @@ public class MigrationTest extends AbstractKeycloakTest {
}
private void testAuthorizationServices(RealmResource... realms) {
+ log.info("testing authorization services");
for (RealmResource realm : realms) {
//test setup of authorization services
for (String roleName : Constants.AUTHZ_DEFAULT_AUTHORIZATION_ROLES) {
@@ -270,6 +277,7 @@ public class MigrationTest extends AbstractKeycloakTest {
}
private void testNameOfOTPRequiredAction(RealmResource... realms) {
+ log.info("testing OTP Required Action");
for (RealmResource realm : realms) {
RequiredActionProviderRepresentation otpAction = realm.flows().getRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name());
@@ -278,6 +286,7 @@ public class MigrationTest extends AbstractKeycloakTest {
}
private void testIdentityProviderAuthenticator(RealmResource... realms) {
+ log.info("testing identity provider authenticator");
for (RealmResource realm : realms) {
boolean success = false;
for (AuthenticationFlowRepresentation flow : realm.flows().getFlows()) {
@@ -298,6 +307,7 @@ public class MigrationTest extends AbstractKeycloakTest {
}
private void testUpdateProtocolMappers(RealmResource... realms) {
+ log.info("testing updated protocol mappers");
for (RealmResource realm : realms) {
for (ClientRepresentation client : realm.clients().findAll()) {
for (ProtocolMapperRepresentation protocolMapper : client.getProtocolMappers()) {
@@ -320,6 +330,7 @@ public class MigrationTest extends AbstractKeycloakTest {
}
private void testDuplicateEmailSupport(RealmResource... realms) {
+ log.info("testing duplicate email");
for (RealmResource realm : realms) {
RealmRepresentation rep = realm.toRepresentation();
assertTrue("LoginWithEmailAllowed should be enabled.", rep.isLoginWithEmailAllowed());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java
index 9de5ae2..12fe4a1 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java
@@ -61,6 +61,11 @@ public class ClientBuilder {
return this;
}
+ public ClientBuilder consentRequired(boolean consentRequired) {
+ rep.setConsentRequired(consentRequired);
+ return this;
+ }
+
public ClientBuilder publicClient() {
rep.setPublicClient(true);
return this;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-2.2.1.Final.json b/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-2.2.1.Final.json
index e0b0d83..910905f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-2.2.1.Final.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-2.2.1.Final.json
@@ -1,4937 +1,3 @@
-[
- {
- "id": "master",
- "realm": "master",
- "displayName": "Keycloak",
- "displayNameHtml": "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
- "notBefore": 0,
- "revokeRefreshToken": false,
- "accessTokenLifespan": 60,
- "accessTokenLifespanForImplicitFlow": 900,
- "ssoSessionIdleTimeout": 1800,
- "ssoSessionMaxLifespan": 36000,
- "offlineSessionIdleTimeout": 2592000,
- "accessCodeLifespan": 60,
- "accessCodeLifespanUserAction": 300,
- "accessCodeLifespanLogin": 1800,
- "enabled": true,
- "sslRequired": "external",
- "registrationAllowed": false,
- "registrationEmailAsUsername": false,
- "rememberMe": false,
- "verifyEmail": false,
- "resetPasswordAllowed": false,
- "editUsernameAllowed": false,
- "bruteForceProtected": false,
- "maxFailureWaitSeconds": 900,
- "minimumQuickLoginWaitSeconds": 60,
- "waitIncrementSeconds": 60,
- "quickLoginCheckMilliSeconds": 1000,
- "maxDeltaTimeSeconds": 43200,
- "failureFactor": 30,
- "privateKey": "MIIEowIBAAKCAQEAiU54OXoCbHy0L0gHn1yasctcnKHRU1pHFIJnWvaI7rClJydet9dDJaiYXOxMKseiBm3eYznfN3cPyU8udYmRnMuKjiocZ77LT2IEttAjXb6Ggazx7loriFHRy0IOJeX4KxXhAPWmxqa3mkFNfLBEvFqVaBgUDHQ60cmnPvNSHYudBTW9K80s8nvmP2pso7HTwWJ1+Xatj1Ey/gTmB3CXlyqBegGWC9TeuErEYpYhdh+11TVWasgMBZyUCtL3NRPaBuhaPg1LpW8lWGk05nS+YM6dvTk3Mppv+z2RygEpxyO09oT3b4G+Zfwit1STqn0AvDTGzINdoKcNtFScV0j8TwIDAQABAoIBAHcbPKsPLZ8SJfOF1iblW8OzFulAbaaSf2pJHIMJrQrw7LKkMkPjVXoLX+/rgr7xYZmWIP2OLBWfEHCeYTzQUyHiZpSf7vgHx7Fa45/5uVQOe/ttHIiYa37bCtP4vvEdJkOpvP7qGPvljwsebqsk9Ns28LfVez66bHOjK5Mt2yOIulbTeEs7ch//h39YwKJv96vc+CHbV2O6qoOxZessO6y+287cOBvbFXmS2GaGle5Nx/EwncBNS4b7czoetmm70+9ht3yX+kxaP311YUT31KQjuaJt275kOiKsrXr27PvgO++bsIyGuSzqyS7G7fmxF2zUyphEqEpalyDGMKMnrAECgYEA1fCgFox03rPDjm0MhW/ThoS2Ld27sbWQ6reS+PBMdUTJZVZIU1D2//h6VXDnlddhk6avKjA4smdy1aDKzmjz3pt9AKn+kgkXqtTC2fD3wp+fC9hND0z+rQPGe/Gk7ZUnTdsqnfyowxr+woIgzdnRukOUrG+xQiP3RUUT7tt6NQECgYEApEz2xvgqMm+9/f/YxjLdsFUfLqc4WlafB863stYEVqlCYy5ujyo0VQ0ahKSKJkLDnf52+aMUqPOpwaGePpu3O6VkvpcKfPY2MUlZW7/6Sa9et9hxNkdTS7Gui2d1ELpaCBe1Bc62sk8EA01iHXE1PpvyUqDWrhNh+NrDICA9oU8CgYBgGDYACtTP11TmW2r9YK5VRLUDww30k4ZlN1GnyV++aMhBYVEZQ0u+y+A/EnijIFwu0vbo70H4OGknNZMCxbeMbLDoJHM5KyZbUDe5ZvgSjloFGwH59m6KTiDQOUkIgi9mVCQ/VGaFRFHcElEjxUvj60kTbxPijn8ZuR5r8l9hAQKBgQCQ9jL5pHWeoIayN20smi6M6N2lTPbkhe60dcgQatHTIG2pkosLl8IqlHAkPgSB84AiwyR351JQKwRJCm7TcJI/dxMnMZ6YWKfB3qSP1hdfsfJRJQ/mQxIUBAYrizF3e+P5peka4aLCOgMhYsJBlePThMZN7wja99EGPwXQL4IQ8wKBgB8Nis1lQK6Z30GCp9u4dYleGfEP71Lwqvk/eJb89/uz0fjF9CTpJMULFc+nA5u4yHP3LFnRg3zCU6aEwfwUyk4GH9lWGV/qIAisQtgrCEraVe4qxz0DVE59C7qjO26IhU2U66TEzPAqvQ3zqey+woDn/cz/JMWK1vpcSk+TKn3K",
- "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiU54OXoCbHy0L0gHn1yasctcnKHRU1pHFIJnWvaI7rClJydet9dDJaiYXOxMKseiBm3eYznfN3cPyU8udYmRnMuKjiocZ77LT2IEttAjXb6Ggazx7loriFHRy0IOJeX4KxXhAPWmxqa3mkFNfLBEvFqVaBgUDHQ60cmnPvNSHYudBTW9K80s8nvmP2pso7HTwWJ1+Xatj1Ey/gTmB3CXlyqBegGWC9TeuErEYpYhdh+11TVWasgMBZyUCtL3NRPaBuhaPg1LpW8lWGk05nS+YM6dvTk3Mppv+z2RygEpxyO09oT3b4G+Zfwit1STqn0AvDTGzINdoKcNtFScV0j8TwIDAQAB",
- "certificate": "MIICmzCCAYMCBgFXt/Tg9TANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMTYxMDEyMDgxMjQxWhcNMjYxMDEyMDgxNDIxWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJTng5egJsfLQvSAefXJqxy1ycodFTWkcUgmda9ojusKUnJ16310MlqJhc7Ewqx6IGbd5jOd83dw/JTy51iZGcy4qOKhxnvstPYgS20CNdvoaBrPHuWiuIUdHLQg4l5fgrFeEA9abGpreaQU18sES8WpVoGBQMdDrRyac+81Idi50FNb0rzSzye+Y/amyjsdPBYnX5dq2PUTL+BOYHcJeXKoF6AZYL1N64SsRiliF2H7XVNVZqyAwFnJQK0vc1E9oG6Fo+DUulbyVYaTTmdL5gzp29OTcymm/7PZHKASnHI7T2hPdvgb5l/CK3VJOqfQC8NMbMg12gpw20VJxXSPxPAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAC54wFHL8tmrksq4OzatzNUM+R+3Hu/VXX3T44dwg0EvXzGW45sME+gKCuleU1PabIrr6oFm0bBMTdxgE2hbLWpYbU3OcsjArpCeCsOlxrAkqhVQN161J+tp77JkDMgArFdwe3wh5bhvLaOZSt6Fsq+oo16CXG1obe1feyaK3+sU3YuDUIHE01UYtvwtfDsYBC+VDyTdNDbB15WcdRoGljJY/JiT0JHdmAfq8qdGDuxGocIV0lSB8bO5JwF/WCmKqMrnh5j1NfGcE1g26Hbz2RmDs17X0K10Okzs/qz1YZqDjPVYiU//VFQQro71/D35dPOJv8mQMjhjNaXScL44h7w=",
- "codeSecret": "4c59c2db-d9c3-4023-8cd5-8808fe854e98",
- "roles": {
- "realm": [
- {
- "id": "40dd3051-9581-479d-9ae0-80abd28b3f94",
- "name": "create-realm",
- "description": "${role_create-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false
- },
- {
- "id": "b4693527-02c6-4e26-b1e2-b2249138304c",
- "name": "master-test-realm-role",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false
- },
- {
- "id": "5e030453-7094-42a5-8fd2-ce88c46c1172",
- "name": "admin",
- "description": "${role_admin}",
- "scopeParamRequired": false,
- "composite": true,
- "composites": {
- "realm": [
- "create-realm"
- ],
- "client": {
- "Migration-realm": [
- "view-users",
- "manage-users",
- "view-clients",
- "manage-identity-providers",
- "manage-clients",
- "impersonation",
- "create-client",
- "manage-events",
- "manage-realm",
- "view-realm",
- "view-authorization",
- "view-events",
- "manage-authorization",
- "view-identity-providers"
- ],
- "master-realm": [
- "view-identity-providers",
- "manage-realm",
- "create-client",
- "manage-users",
- "impersonation",
- "view-clients",
- "manage-authorization",
- "view-realm",
- "manage-events",
- "view-authorization",
- "view-users",
- "manage-identity-providers",
- "view-events",
- "manage-clients"
- ]
- }
- },
- "clientRole": false
- },
- {
- "id": "311339f9-a82d-4960-a06a-63775649ac50",
- "name": "uma_authorization",
- "description": "${role_uma_authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false
- },
- {
- "name": "user",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false
- },
- {
- "id": "dc09cba8-f24d-4731-9169-47a951e519eb",
- "name": "offline_access",
- "description": "${role_offline-access}",
- "scopeParamRequired": true,
- "composite": false,
- "clientRole": false
- }
- ],
- "client": {
- "security-admin-console": [],
- "master-test-client": [
- {
- "id": "9c25e418-2415-43f1-90ef-1627272e22ef",
- "name": "master-test-client-role",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6268e266-346b-46ba-8408-fe17b5792b10"
- }
- ],
- "admin-cli": [],
- "Migration-realm": [
- {
- "id": "4bd2a237-8e0e-4909-b8d5-f1635d442f3c",
- "name": "manage-events",
- "description": "${role_manage-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "0b9bb67b-16a3-4490-bd74-bf0aad1c43df",
- "name": "manage-realm",
- "description": "${role_manage-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "2038d832-6869-4bdd-94d7-abb605ec117b",
- "name": "view-realm",
- "description": "${role_view-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "85bcb1ac-257f-4d95-93e3-7f905c91bda0",
- "name": "view-authorization",
- "description": "${role_view-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "9c31faa8-e91d-4f71-ba5e-0cdb309a6c1b",
- "name": "view-events",
- "description": "${role_view-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "b7e97e07-c666-4e55-8c2b-127013fb70b2",
- "name": "manage-authorization",
- "description": "${role_manage-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "2567bcf2-532a-4950-95ec-18a8e993cbe8",
- "name": "view-users",
- "description": "${role_view-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "b3d7e97c-e6fe-418f-a354-7ad0c63efe72",
- "name": "manage-users",
- "description": "${role_manage-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "4881d187-699e-4130-9ca7-7afd71b7132f",
- "name": "view-clients",
- "description": "${role_view-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "c22bb7bf-9a27-40e4-af54-f452a17eb532",
- "name": "manage-identity-providers",
- "description": "${role_manage-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "f694e360-1635-479e-b4d6-e71a8a615ab8",
- "name": "view-identity-providers",
- "description": "${role_view-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "b2f38b33-aad3-4086-8c23-dafee15439cb",
- "name": "manage-clients",
- "description": "${role_manage-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "68b32df6-687f-4dd2-a93e-59f807cb3a4c",
- "name": "impersonation",
- "description": "${role_impersonation}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "500cae23-30a8-4221-96ca-1b4d15adae62",
- "name": "create-client",
- "description": "${role_create-client}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- }
- ],
- "broker": [
- {
- "id": "fefd0452-1eb5-40f6-aaec-b65fe38ae9b9",
- "name": "read-token",
- "description": "${role_read-token}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "5bcab424-560b-4653-b490-b03db075ecda"
- }
- ],
- "master-realm": [
- {
- "id": "c0303a3e-0663-4346-8321-85ebe587c0df",
- "name": "view-events",
- "description": "${role_view-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "08e2c729-09ee-42e0-8106-1a712f0f5d59",
- "name": "view-identity-providers",
- "description": "${role_view-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "0c339131-888a-4e00-a999-b2ac5cc8f891",
- "name": "manage-realm",
- "description": "${role_manage-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "3310eabb-f4d5-40fd-9aee-84c658f3c66f",
- "name": "create-client",
- "description": "${role_create-client}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "e6217299-9180-4be5-83ec-1f92645fbf3e",
- "name": "manage-users",
- "description": "${role_manage-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "4aeeab55-7859-4fbb-8f98-fb20919c98b4",
- "name": "impersonation",
- "description": "${role_impersonation}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "1f8f140a-1574-4ee8-9b91-360b2ae76e1b",
- "name": "view-clients",
- "description": "${role_view-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "181269dc-bfec-47d9-9946-6ebb9bbe36d6",
- "name": "manage-authorization",
- "description": "${role_manage-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "1d3757e9-167e-406c-93e6-5d30e9b819de",
- "name": "view-realm",
- "description": "${role_view-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "abb6146d-1cd0-4d03-b74f-f448d8675409",
- "name": "manage-events",
- "description": "${role_manage-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "61486848-4bad-4ba2-bc46-bfae4a0a889f",
- "name": "view-authorization",
- "description": "${role_view-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "e2fc9a91-9415-41f9-b1cd-2f9456edb53e",
- "name": "manage-clients",
- "description": "${role_manage-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "85131bab-8020-474f-bb70-76e78886df2b",
- "name": "view-users",
- "description": "${role_view-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "e8d6d361-b58a-4739-8747-687e5b1628e8",
- "name": "manage-identity-providers",
- "description": "${role_manage-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- }
- ],
- "account": [
- {
- "id": "d2bf38f4-09fe-473a-b33f-18c1ff674705",
- "name": "manage-account",
- "description": "${role_manage-account}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "08a0990d-8288-4ba7-ba1e-0828cd1e002a"
- },
- {
- "id": "2f57d1ae-d6ca-488b-9395-ddf3f80e7c9d",
- "name": "view-profile",
- "description": "${role_view-profile}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "08a0990d-8288-4ba7-ba1e-0828cd1e002a"
- }
- ]
- }
- },
- "groups": [
- {
- "id": "e6a9423c-2140-4c31-ba18-dd517b2b900a",
- "name": "master-test-group",
- "path": "/master-test-group",
- "attributes": {},
- "realmRoles": [],
- "clientRoles": {},
- "subGroups": []
- }
- ],
- "defaultRoles": [
- "offline_access",
- "uma_authorization"
- ],
- "requiredCredentials": [
- "password"
- ],
- "passwordPolicy": "hashIterations(20000)",
- "otpPolicyType": "totp",
- "otpPolicyAlgorithm": "HmacSHA1",
- "otpPolicyInitialCounter": 0,
- "otpPolicyDigits": 6,
- "otpPolicyLookAheadWindow": 1,
- "otpPolicyPeriod": 30,
- "users": [
- {
- "id": "c345ea0f-1c90-4a45-9b2f-96a381ca5a5b",
- "createdTimestamp": 1476265539362,
- "username": "admin",
- "enabled": true,
- "totp": false,
- "emailVerified": false,
- "credentials": [
- {
- "type": "password",
- "hashedSaltedValue": "YwCkHJ6u5ZROE/WkQgI6NHvg06bkbOy5eaz8M9fnLDTajjZqQfZELI8NmrQecCPXY8/GEI9jN1gL/5Y3yulIVA==",
- "salt": "MLKqip78LpUnPDBsNDAf8g==",
- "hashIterations": 20000,
- "counter": 0,
- "algorithm": "pbkdf2",
- "digits": 0,
- "createdDate": 1476265539000
- }
- ],
- "requiredActions": [],
- "realmRoles": [
- "admin",
- "uma_authorization",
- "offline_access"
- ],
- "clientRoles": {
- "account": [
- "manage-account",
- "view-profile"
- ]
- },
- "groups": []
- },
- {
- "id": "f9d17688-5a5f-40f2-829b-4444ede51f6f",
- "createdTimestamp": 1476265646817,
- "username": "master-test-user",
- "enabled": true,
- "totp": false,
- "emailVerified": false,
- "credentials": [],
- "requiredActions": [],
- "realmRoles": [
- "uma_authorization",
- "offline_access"
- ],
- "clientRoles": {
- "account": [
- "manage-account",
- "view-profile"
- ]
- },
- "groups": [
- "/master-test-group"
- ]
- }
- ],
- "scopeMappings": [
- {
- "client": "admin-cli",
- "roles": [
- "admin"
- ]
- },
- {
- "client": "security-admin-console",
- "roles": [
- "admin"
- ]
- }
- ],
- "clients": [
- {
- "id": "c3aca840-5187-406e-9b1a-b62a57eb371a",
- "clientId": "Migration-realm",
- "name": "Migration Realm",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "29958e6c-6f44-47a6-9810-770ea90b7387",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": true,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "d009ceb4-cb36-4abe-8425-e6df2737e627",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "24981db4-6740-4e08-a505-3aabe8e350c3",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "9ca7f1b4-170d-4d75-a94b-26511318bf2c",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "41482c5e-6c4c-4618-b819-bcb6e693caee",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "df1d77fa-2b6c-49fd-9785-2ee51ff937fd",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "5e90ad8d-98c0-4cc1-a74e-933cb77e82a6",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "08a0990d-8288-4ba7-ba1e-0828cd1e002a",
- "clientId": "account",
- "name": "${client_account}",
- "baseUrl": "/auth/realms/master/account",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "532d4ec6-0ff4-448e-bdfc-11b87efb50d3",
- "defaultRoles": [
- "view-profile",
- "manage-account"
- ],
- "redirectUris": [
- "/auth/realms/master/account/*"
- ],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "bfc0fe7c-1bdb-4d51-8cbb-93f3923683c8",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "6f500b7d-f16a-410f-a567-d4f38fc45c5e",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "b37bfe8a-94de-4893-b86e-b642c267d72b",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "7abb3444-776a-4537-928a-e1caf83c6df8",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "01314df4-5726-4855-b71d-aaedcee9604b",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "4a16b178-40ef-4a88-94e8-330fe92405d2",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "9da2f23b-767b-4d99-8d24-a1cab6afe448",
- "clientId": "admin-cli",
- "name": "${client_admin-cli}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "3b37796a-29ee-46b8-b606-12ea19d40097",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": false,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "1631e30c-79b1-4a24-bbd7-a2833100d140",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7a19f140-f951-4505-b200-46b41ccdeed3",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "d6b5b848-2575-4de6-b2cd-cf692b0daa22",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "94a1d7ad-b103-491e-9b76-65f763420d0a",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "ed2d7ce3-3f24-4412-8ee0-91a8ab22913a",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "c342307c-9fb2-4e7d-9bf7-a18985227483",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "5bcab424-560b-4653-b490-b03db075ecda",
- "clientId": "broker",
- "name": "${client_broker}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "6613ea12-47d2-4e07-bcae-329211df19c9",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "eebc4c71-63f9-4c51-abb9-0577f1188399",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "73bbb61d-f87a-4d52-a0ce-3f675b79d808",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "3172c3dd-7253-4546-9ff0-735f4635a5f3",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "895bf3d3-21dc-478c-9aad-dedc148518a3",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "40e1c333-168c-444b-9ae5-5d4fd9f07a82",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "974e0506-401d-4ff0-a43c-6f9d63920473",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "470a14ef-efb5-4686-85a0-0738edd1f8d3",
- "clientId": "master-realm",
- "name": "master Realm",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "70bb98e1-51ed-4ebb-a103-1e2cad38a292",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": true,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "b9f0a1d5-9a56-4c42-938b-54b9aae180e4",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "629ba061-ee90-4893-9a3c-6ebb1cb8586f",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "e02314bb-f3de-4f72-874c-2ccb30727e52",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "c82eaace-135c-4373-ac99-d09469bc1b12",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "a82fe8ca-df8d-4ad7-bbfd-c5f0adfd8cd2",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "44ae3204-8f77-4a7d-ac7f-c44bafed3ad2",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "6268e266-346b-46ba-8408-fe17b5792b10",
- "clientId": "master-test-client",
- "name": "master-test-client",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "271c50a7-6a20-4a27-bb94-97136ffb1539",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": -1,
- "protocolMappers": [
- {
- "id": "191b5693-2fdd-4029-8657-681facc51dfb",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "079b1dba-1ac0-4d3d-94b7-d8468dc55962",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "1fc5cdff-d1ba-4492-83df-f81d3820c31a",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "8a443f85-23c0-4ee6-9e31-4b5ad571aa94",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7b5f4689-ede2-427b-b8dc-289791ac6cad",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "b1af3b5e-fff1-41c2-b091-0c35a6c84793",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "a27cd9f4-e9f3-45d9-aef1-0509a8337de0",
- "clientId": "security-admin-console",
- "name": "${client_security-admin-console}",
- "baseUrl": "/auth/admin/master/console/index.html",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "f7f2c609-8902-4db2-9350-685b0423457b",
- "redirectUris": [
- "/auth/admin/master/console/*"
- ],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "a7dd5e41-4d47-41fe-b5ad-33e1ad801f31",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "4c89dd7c-d865-4557-aa52-d25e83c70789",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "d4fa50be-3a2f-4d4c-9123-a5d99b8315e5",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "8bf5feae-36bd-49f5-8a2e-19093ee92a29",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "2b8281b5-e2a8-4868-92f8-76097648f328",
- "name": "locale",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "consentText": "${locale}",
- "config": {
- "user.attribute": "locale",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "locale",
- "jsonType.label": "String"
- }
- },
- {
- "id": "20551202-834b-4f9d-9582-6f27d58b604d",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "f205e545-5b2d-4436-b9c8-88a07de1ea7d",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- }
- ],
- "clientTemplates": [],
- "browserSecurityHeaders": {
- "xContentTypeOptions": "nosniff",
- "xFrameOptions": "SAMEORIGIN",
- "contentSecurityPolicy": "frame-src 'self'"
- },
- "smtpServer": {},
- "eventsEnabled": false,
- "eventsListeners": [
- "jboss-logging"
- ],
- "enabledEventTypes": [],
- "adminEventsEnabled": false,
- "adminEventsDetailsEnabled": false,
- "components": {},
- "internationalizationEnabled": false,
- "supportedLocales": [],
- "authenticationFlows": [
- {
- "id": "7823af6c-d339-4b0c-a786-83d7dbba3052",
- "alias": "Handle Existing Account",
- "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-confirm-link",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "idp-email-verification",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "Verify Existing Account by Re-authentication",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "506407b8-40db-4e67-99f7-4d21549a72ea",
- "alias": "Verify Existing Account by Re-authentication",
- "description": "Reauthentication of existing account",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "f5ab7c19-2940-4b1d-8ce3-cca8014501a3",
- "alias": "browser",
- "description": "browser based authentication",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-cookie",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-spnego",
- "requirement": "DISABLED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "identity-provider-redirector",
- "requirement": "ALTERNATIVE",
- "priority": 25,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "forms",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "a0dca221-6b16-447c-960b-50d0231a579b",
- "alias": "clients",
- "description": "Base authentication for clients",
- "providerId": "client-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "client-secret",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-jwt",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "2fc9e6fe-23e4-4d5d-8de7-7df4352cc92f",
- "alias": "direct grant",
- "description": "OpenID Connect Resource Owner Grant",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "direct-grant-validate-username",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-password",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-otp",
- "requirement": "OPTIONAL",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "8e4c82e6-1981-4877-b97a-4ef5c1981d05",
- "alias": "first broker login",
- "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticatorConfig": "review profile config",
- "authenticator": "idp-review-profile",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticatorConfig": "create unique user config",
- "authenticator": "idp-create-user-if-unique",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "Handle Existing Account",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "10f78331-e0d5-4a99-be02-7fc1f5d31215",
- "alias": "forms",
- "description": "Username, password, otp and other auth forms.",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "f6a0beb4-7fd1-4c83-afe9-44518f45ed7b",
- "alias": "registration",
- "description": "registration flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-page-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "flowAlias": "registration form",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "b4029db6-dc6e-44a5-b685-86e394ff7dfb",
- "alias": "registration form",
- "description": "registration form",
- "providerId": "form-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-user-creation",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-profile-action",
- "requirement": "REQUIRED",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-password-action",
- "requirement": "REQUIRED",
- "priority": 50,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-recaptcha-action",
- "requirement": "DISABLED",
- "priority": 60,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "2758d06b-35da-43a7-83dc-ec02e5ffc1be",
- "alias": "reset credentials",
- "description": "Reset credentials for a user if they forgot their password or something",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "reset-credentials-choose-user",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-credential-email",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-password",
- "requirement": "REQUIRED",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-otp",
- "requirement": "OPTIONAL",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "b1927d79-54d8-4b5f-a01a-f4d5be8d3769",
- "alias": "saml ecp",
- "description": "SAML ECP Profile Authentication Flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "http-basic-authenticator",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- }
- ],
- "authenticatorConfig": [
- {
- "id": "e40c22b1-546d-4df6-8798-dca761db8cf0",
- "alias": "create unique user config",
- "config": {
- "require.password.update.after.registration": "false"
- }
- },
- {
- "id": "bacdeb1b-bfc5-4adc-9a3e-798d8dd6a6da",
- "alias": "review profile config",
- "config": {
- "update.profile.on.first.login": "missing"
- }
- }
- ],
- "requiredActions": [
- {
- "alias": "CONFIGURE_TOTP",
- "name": "Configure OTP",
- "providerId": "CONFIGURE_TOTP",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "UPDATE_PASSWORD",
- "name": "Update Password",
- "providerId": "UPDATE_PASSWORD",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "UPDATE_PROFILE",
- "name": "Update Profile",
- "providerId": "UPDATE_PROFILE",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "VERIFY_EMAIL",
- "name": "Verify Email",
- "providerId": "VERIFY_EMAIL",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "terms_and_conditions",
- "name": "Terms and Conditions",
- "providerId": "terms_and_conditions",
- "enabled": false,
- "defaultAction": false,
- "config": {}
- }
- ],
- "browserFlow": "browser",
- "registrationFlow": "registration",
- "directGrantFlow": "direct grant",
- "resetCredentialsFlow": "reset credentials",
- "clientAuthenticationFlow": "clients",
- "attributes": {
- "_browser_header.xFrameOptions": "SAMEORIGIN",
- "failureFactor": "30",
- "quickLoginCheckMilliSeconds": "1000",
- "maxDeltaTimeSeconds": "43200",
- "displayName": "Keycloak",
- "_browser_header.xContentTypeOptions": "nosniff",
- "bruteForceProtected": "false",
- "maxFailureWaitSeconds": "900",
- "_browser_header.contentSecurityPolicy": "frame-src 'self'",
- "minimumQuickLoginWaitSeconds": "60",
- "displayNameHtml": "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
- "waitIncrementSeconds": "60"
- },
- "keycloakVersion": "2.2.1.Final"
- },
- {
- "id": "Migration",
- "realm": "Migration",
- "notBefore": 0,
- "revokeRefreshToken": false,
- "accessTokenLifespan": 300,
- "accessTokenLifespanForImplicitFlow": 900,
- "ssoSessionIdleTimeout": 1800,
- "ssoSessionMaxLifespan": 36000,
- "offlineSessionIdleTimeout": 2592000,
- "accessCodeLifespan": 60,
- "accessCodeLifespanUserAction": 300,
- "accessCodeLifespanLogin": 1800,
- "enabled": true,
- "sslRequired": "external",
- "registrationAllowed": false,
- "registrationEmailAsUsername": false,
- "rememberMe": false,
- "verifyEmail": false,
- "resetPasswordAllowed": false,
- "editUsernameAllowed": false,
- "bruteForceProtected": false,
- "maxFailureWaitSeconds": 900,
- "minimumQuickLoginWaitSeconds": 60,
- "waitIncrementSeconds": 60,
- "quickLoginCheckMilliSeconds": 1000,
- "maxDeltaTimeSeconds": 43200,
- "failureFactor": 30,
- "privateKey": "MIIEpAIBAAKCAQEApt6gCllWkVTZ7fy/oRIx6Bxjt9x3eKKyKGFXvN4iaafrNqpYU9lcqPngWJ9DyXGqUf8RpjPaQWiLWLxjw3xGBqLk2E1/Frb9e/dy8rj//fHGq6bujN1iguzyFwxPGT5Asd7jflRI3qU04M8JE52PArqPhGL2Fn+FiSK5SWRIGm+hVL7Ck/E/tVxM25sFG1/UTQqvrROm4q76TmP8FsyZaTLVf7cCwW2QPIX0N5HTVb3QbBb5KIsk4kKmk/g7uUxS9r42tu533LISzRr5CTyWZAL2XFRuF2RrKdE8gwqkEubw6sDmB2mE0EoPdY1DUhBQgVP/5rwJrCtTsUBR2xdEYQIDAQABAoIBAFbbsNBSOlZBpYJUOmcb8nBQPrOYhXN8tGGCccn0klMOvcdhmcJjdPDbyCQ5Gm7DxJUTwNsTSHsdcNMKlJ9Pk5+msJnKlOl87KrXXbTsCQvlCrWUmb0nCzz9GvJWTOHl3oT3cND0DE4gDksqWR4luCgCdevCGzgQvrBoK6wBD+r578uEW3iw10hnJ0+wnGiw8IvPzE1a9xbY4HD8/QrYdaLxuLb/aC1PDuzrz0cOjnvPkrws5JrbUSnbFygJiOv1z4l2Q00uGIxlHtXdwQBnTZZjVi4vOec2BYSHffgwDYEZIglw1mnrV7y0N1nnPbtJK/cegIkXoBQHXm8Q99TrWMUCgYEA9au86qcwrXZZg5H4BpR5cpy0MSkcKDbA1aRL1cAyTCqJxsczlAtLhFADF+NhnlXj4y7gwDEYWrz064nF73I+ZGicvCiyOy+tCTugTyTGS+XR948ElDMS6PCUUXsotS3dKa0b3c9wd2mxeddTjq/ArfgEVZJ6fE1KtjLt9dtfA+8CgYEAreK3JsvjR5b/Xct28TghYUU7Qnasombb/shqqy8FOMjYUr5OUm/OjNIgoCqhOlE8oQDJ4dOZofNSa7tL+oM8Gmbal+E3fRzxnx/9/EC4QV6sVaPLTIyk7EPfKTcZuzH7+BNZtAziTxJw9d6YJQRbkpg92EZIEoR8iDj2Xs5xrK8CgYEAwMVWwwYX8zT3vn7ukTM2LRH7bsvkVUXJgJqgCwT6Mrv6SmkK9vL5+cPS+Y6pjdW1sRGauBSOGL1Grf/4ug/6F03jFt4UJM8fRyxreU7Q7sNSQ6AMpsGA6BnHODycz7ZCYa59PErG5FyiL4of/cm5Nolz1TXQOPNpWZiTEqVlZC8CgYA4YPbjVF4nuxSnU64H/hwMjsbtAM9uhI016cN0J3W4+J3zDhMU9X1x+Tts0wWdg/N1fGz4lIQOl3cUyRCUc/KL2OdtMS+tmDHbVyMho9ZaE5kq10W2Vy+uDz+O/HeSU12QDK4cC8Vgv+jyPy7zaZtLR6NduUPrBRvfiyCOkr8WrwKBgQCY0h4RCdNFhr0KKLLmJipAtV8wBCGcg1jY1KoWKQswbcykfBKwHbF6EooVqkRW0ITjWB7ZZCf8TnSUxe0NXCUAkVBrhzS4DScgtoSZYOOUaSHgOxpfwgnQ3oYotKi98Yg3IsaLs1j4RuPG5Sp1z6o+ELP1uvr8azyn9YlLa+523Q==",
- "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApt6gCllWkVTZ7fy/oRIx6Bxjt9x3eKKyKGFXvN4iaafrNqpYU9lcqPngWJ9DyXGqUf8RpjPaQWiLWLxjw3xGBqLk2E1/Frb9e/dy8rj//fHGq6bujN1iguzyFwxPGT5Asd7jflRI3qU04M8JE52PArqPhGL2Fn+FiSK5SWRIGm+hVL7Ck/E/tVxM25sFG1/UTQqvrROm4q76TmP8FsyZaTLVf7cCwW2QPIX0N5HTVb3QbBb5KIsk4kKmk/g7uUxS9r42tu533LISzRr5CTyWZAL2XFRuF2RrKdE8gwqkEubw6sDmB2mE0EoPdY1DUhBQgVP/5rwJrCtTsUBR2xdEYQIDAQAB",
- "certificate": "MIICoTCCAYkCBgFXt/t9TjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlNaWdyYXRpb24wHhcNMTYxMDEyMDgxOTU0WhcNMjYxMDEyMDgyMTM0WjAUMRIwEAYDVQQDDAlNaWdyYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCm3qAKWVaRVNnt/L+hEjHoHGO33Hd4orIoYVe83iJpp+s2qlhT2Vyo+eBYn0PJcapR/xGmM9pBaItYvGPDfEYGouTYTX8Wtv1793LyuP/98carpu6M3WKC7PIXDE8ZPkCx3uN+VEjepTTgzwkTnY8Cuo+EYvYWf4WJIrlJZEgab6FUvsKT8T+1XEzbmwUbX9RNCq+tE6birvpOY/wWzJlpMtV/twLBbZA8hfQ3kdNVvdBsFvkoiyTiQqaT+Du5TFL2vja27nfcshLNGvkJPJZkAvZcVG4XZGsp0TyDCqQS5vDqwOYHaYTQSg91jUNSEFCBU//mvAmsK1OxQFHbF0RhAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFtPdVUB65dAP6v2wu8idPkkqRaP5gmcOuOt2+8/slx7RvO/FFwzFvAqroqmpaKJ53daewZwIG4Wzu4lziqYnD3F3YoqxqUY8ID58SLm9a6XF6aYka7TxXJnZgmy7v1ZWcbbTinvUC7S1m23imT7779cWj5NkkXSM/R+RWB8ZAQCpy9pg7iElAMTlqAp31pCntNG3l1O13A6t5eN3Af474T0FjVaXIEG/PLcRmF/5kTwmkYy5Av1v2vmyLBYXKNUrWwjeTGEEX0+j9AkcF79D1GpdKZpvuC0wxOrOgHLiR9DpGucMJajx+RA8zbAAj5C1A5JfkKBZPh2jMQ06c2eAAM=",
- "codeSecret": "be7e5acb-ad90-4c01-8dfe-c78cc492b752",
- "roles": {
- "realm": [
- {
- "id": "a3e9f038-0c6d-4024-8a2a-ce3958c7afbb",
- "name": "offline_access",
- "description": "${role_offline-access}",
- "scopeParamRequired": true,
- "composite": false,
- "clientRole": false,
- "containerId": "Migration"
- },
- {
- "id": "fb9bc1ec-b542-40c5-a49b-b71b985fa545",
- "name": "migration-test-realm-role",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false,
- "containerId": "Migration"
- },
- {
- "id": "5291ac52-5bc2-4e0c-900f-907718ff4fbe",
- "name": "uma_authorization",
- "description": "${role_uma_authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false,
- "containerId": "Migration"
- }
- ],
- "client": {
- "migration-test-client": [
- {
- "id": "36a5eb7f-8bca-441c-bb60-32a8f6762886",
- "name": "migration-test-client-role",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "f66de6ed-4fd8-47b6-a2db-85ab8ed88874"
- }
- ],
- "realm-management": [
- {
- "id": "a14c386a-09d2-463b-9bd5-de6b3bd4e84d",
- "name": "manage-users",
- "description": "${role_manage-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "6b0cab01-7222-48e1-8dc8-49f406c0de4c",
- "name": "manage-realm",
- "description": "${role_manage-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "cc218701-6d4f-4caf-a3ab-bed15e45b366",
- "name": "manage-authorization",
- "description": "${role_manage-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "c8fdf4fb-e568-44eb-8ea3-08b4397220b8",
- "name": "realm-admin",
- "description": "${role_realm-admin}",
- "scopeParamRequired": false,
- "composite": true,
- "composites": {
- "client": {
- "realm-management": [
- "manage-users",
- "manage-realm",
- "manage-authorization",
- "create-client",
- "view-users",
- "manage-clients",
- "view-identity-providers",
- "impersonation",
- "manage-identity-providers",
- "view-authorization",
- "view-realm",
- "view-events",
- "manage-events",
- "view-clients"
- ]
- }
- },
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "ceb11666-b2bc-43b5-9624-71518c8dfcd0",
- "name": "create-client",
- "description": "${role_create-client}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "db7d163e-1f09-4a30-ad59-9c07ffb865d1",
- "name": "view-users",
- "description": "${role_view-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "a56c4f3b-9dcb-4638-9aa5-1b1a1830cf92",
- "name": "manage-clients",
- "description": "${role_manage-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "dad6affc-1150-4d13-95b0-ff8edd777f65",
- "name": "view-identity-providers",
- "description": "${role_view-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "96a324fc-98eb-44e4-9d12-6cac3ec378b0",
- "name": "impersonation",
- "description": "${role_impersonation}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "78c8c350-f780-4ee7-a28f-89714b2b090a",
- "name": "manage-identity-providers",
- "description": "${role_manage-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "145d8ccc-a362-4f1e-9f7a-aeb84d97ecaa",
- "name": "view-authorization",
- "description": "${role_view-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "b8bd959b-e257-4a24-8eb1-8f00f5c66d0f",
- "name": "view-realm",
- "description": "${role_view-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "caeb8f51-31a3-4ee7-92aa-5de34181aa0f",
- "name": "view-events",
- "description": "${role_view-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "366566bb-1f9a-48e4-85b7-dc02743565bb",
- "name": "manage-events",
- "description": "${role_manage-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- },
- {
- "id": "9777ea7d-e685-4459-afac-3bb4f7ae29b7",
- "name": "view-clients",
- "description": "${role_view-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6bb0386c-713a-4517-8e01-4fa310e7d132"
- }
- ],
- "security-admin-console": [],
- "admin-cli": [],
- "broker": [
- {
- "id": "0e7f7179-a961-4190-8433-f85ede61031a",
- "name": "read-token",
- "description": "${role_read-token}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "da532f35-4b28-477d-a7db-2f7274ea48f7"
- }
- ],
- "account": [
- {
- "id": "5c9fe6a8-1df0-447f-b873-4bdcf697f955",
- "name": "manage-account",
- "description": "${role_manage-account}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "1c308aba-8941-4265-9823-b6e28c7f7b17"
- },
- {
- "id": "39a3116c-cf79-44b9-9690-4f9334f6bc86",
- "name": "view-profile",
- "description": "${role_view-profile}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "1c308aba-8941-4265-9823-b6e28c7f7b17"
- }
- ]
- }
- },
- "groups": [
- {
- "id": "6dcb8223-1027-4553-bac5-bfccc144fe27",
- "name": "migration-test-group",
- "path": "/migration-test-group",
- "attributes": {},
- "realmRoles": [],
- "clientRoles": {},
- "subGroups": []
- }
- ],
- "defaultRoles": [
- "offline_access",
- "uma_authorization"
- ],
- "requiredCredentials": [
- "password"
- ],
- "passwordPolicy": "hashIterations(20000)",
- "otpPolicyType": "totp",
- "otpPolicyAlgorithm": "HmacSHA1",
- "otpPolicyInitialCounter": 0,
- "otpPolicyDigits": 6,
- "otpPolicyLookAheadWindow": 1,
- "otpPolicyPeriod": 30,
- "users": [
- {
- "id": "16c81f28-bd69-4f30-b640-5cc9c02a85e8",
- "createdTimestamp": 1476265711098,
- "username": "migration-test-user",
- "enabled": true,
- "totp": false,
- "emailVerified": false,
- "credentials": [],
- "requiredActions": [],
- "realmRoles": [
- "offline_access",
- "uma_authorization"
- ],
- "clientRoles": {
- "account": [
- "manage-account",
- "view-profile"
- ]
- },
- "groups": [
- "/migration-test-group"
- ]
- }
- ],
- "clientScopeMappings": {
- "realm-management": [
- {
- "client": "admin-cli",
- "roles": [
- "realm-admin"
- ]
- },
- {
- "client": "security-admin-console",
- "roles": [
- "realm-admin"
- ]
- }
- ]
- },
- "clients": [
- {
- "id": "1c308aba-8941-4265-9823-b6e28c7f7b17",
- "clientId": "account",
- "name": "${client_account}",
- "baseUrl": "/auth/realms/Migration/account",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "217ce7f0-4c45-4228-b2df-044f3bb498cf",
- "defaultRoles": [
- "view-profile",
- "manage-account"
- ],
- "redirectUris": [
- "/auth/realms/Migration/account/*"
- ],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "84855aa2-c0a3-44db-80ac-78754d0c18f8",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "cbbca1ca-b4ee-442b-8ad2-909fa4ddc85a",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "857fb389-fd9e-4cf0-8e05-34bf9ece9f07",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "5c79b188-32a0-4426-806e-29e62caa32d7",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "c8224845-17eb-4619-8b22-4f3a5a7cb079",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "6b415e67-09fb-4b4f-961a-2f3da4e63bf4",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "2fd75437-c7e4-47b5-883b-d99587897209",
- "clientId": "admin-cli",
- "name": "${client_admin-cli}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "ee6fac46-0b19-44f2-a1f7-9bea4970fb58",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": false,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "3b31c05a-bf21-4f60-83f8-6795bd8391f8",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "78471104-c0ff-4c31-9bb3-e9dbab5406df",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "e6d1b456-12a8-4d81-8d60-21fd2141788e",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "8fe4300c-5553-410c-9966-57f47e556a04",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "3fae5696-2043-4e24-8d87-289d998fd0f0",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "891904ca-7202-4d60-a6bd-e7f504f6010c",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "da532f35-4b28-477d-a7db-2f7274ea48f7",
- "clientId": "broker",
- "name": "${client_broker}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "cf35eaa4-5e01-4f16-9d23-986372647a71",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "9aa1d878-da61-40da-b73f-3793b9c17d68",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "84ec378e-36f2-4414-be34-66b5d06c65e6",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "e72ee94c-0072-47ca-9ad2-0954445f7667",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "72d559cb-b690-4304-b566-07ab55588c99",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "76988187-9a0a-4061-9774-41d634ec3ea2",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "c17a2767-4293-494c-a362-0e847de0a4dd",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "f66de6ed-4fd8-47b6-a2db-85ab8ed88874",
- "clientId": "migration-test-client",
- "name": "migration-test-client",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "bd3f70d6-90e6-4b74-af6c-9b3033278fce",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": -1,
- "protocolMappers": [
- {
- "id": "5171152e-dd9f-407b-be11-9196a28f482a",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "ed034217-f9e9-4e48-804b-0baa396ae2c4",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "312634ad-55d6-46d8-8a78-723c68441aa1",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "94b49a0f-f16d-4250-adf4-1c2fda791cfb",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "2da7a537-d084-4374-9ada-1c94126fb962",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "8463d358-4d1f-41da-a45e-bbca6abfd416",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "6bb0386c-713a-4517-8e01-4fa310e7d132",
- "clientId": "realm-management",
- "name": "${client_realm-management}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "643e32b1-22df-4ac1-997c-a1b9af2637ef",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": true,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "cfe9b2e9-cccf-4c97-9dfe-322938cbec9c",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "d0edd4ec-9690-4831-bfba-3a6f9535548c",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "fbc372ad-376d-4ffe-92ae-b2df1ca771b6",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "663b75c7-e950-422e-aac3-7e6e1b9c4eec",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "492e1fec-977b-4ada-975f-299b988b7d98",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "00815074-9343-4a44-b769-368e5efa11b4",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "b285ef2d-c740-4241-984c-254744d50cc1",
- "clientId": "security-admin-console",
- "name": "${client_security-admin-console}",
- "baseUrl": "/auth/admin/Migration/console/index.html",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "36ca6c8e-ad8f-4084-ae98-57306af41d48",
- "redirectUris": [
- "/auth/admin/Migration/console/*"
- ],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "ba00003e-72dd-42e4-8927-0c6ff655fd11",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "8f73c93d-5a8e-4925-bbd4-820b833be1d0",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "b4f30163-45a5-4cc3-a5ad-f67f583f2c3d",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "eca008f7-91f1-4b98-b0e6-58785082b9f1",
- "name": "locale",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "consentText": "${locale}",
- "config": {
- "user.attribute": "locale",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "locale",
- "jsonType.label": "String"
- }
- },
- {
- "id": "9680486b-b829-4621-89b5-56a53cfedf58",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "3f0ef567-5cc2-4789-b21f-4bd861af512f",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "46f19d94-672a-403f-ab2f-0ccae755c1de",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- }
- ],
- "clientTemplates": [],
- "browserSecurityHeaders": {
- "xContentTypeOptions": "nosniff",
- "xFrameOptions": "SAMEORIGIN",
- "contentSecurityPolicy": "frame-src 'self'"
- },
- "smtpServer": {},
- "eventsEnabled": false,
- "eventsListeners": [
- "jboss-logging"
- ],
- "enabledEventTypes": [],
- "adminEventsEnabled": false,
- "adminEventsDetailsEnabled": false,
- "components": {},
- "internationalizationEnabled": false,
- "supportedLocales": [],
- "authenticationFlows": [
- {
- "id": "efc32428-2d66-4eab-9c72-3d3072bfe123",
- "alias": "Handle Existing Account",
- "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-confirm-link",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "idp-email-verification",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "Verify Existing Account by Re-authentication",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "9e760226-9a88-4fc8-adb0-db9c39cdcbc9",
- "alias": "Verify Existing Account by Re-authentication",
- "description": "Reauthentication of existing account",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "f8b31433-d2b0-424a-b800-cc20e7276113",
- "alias": "browser",
- "description": "browser based authentication",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-cookie",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-spnego",
- "requirement": "DISABLED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "identity-provider-redirector",
- "requirement": "ALTERNATIVE",
- "priority": 25,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "forms",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "d616b91c-5e69-4792-a770-41bdbfeca227",
- "alias": "clients",
- "description": "Base authentication for clients",
- "providerId": "client-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "client-secret",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-jwt",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "7be60a19-1b3e-4255-9ce5-44fa90694e4e",
- "alias": "direct grant",
- "description": "OpenID Connect Resource Owner Grant",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "direct-grant-validate-username",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-password",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-otp",
- "requirement": "OPTIONAL",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "ac2fe144-8e41-4c59-be25-38532b7fdc7b",
- "alias": "first broker login",
- "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticatorConfig": "review profile config",
- "authenticator": "idp-review-profile",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticatorConfig": "create unique user config",
- "authenticator": "idp-create-user-if-unique",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "Handle Existing Account",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "024d04a3-e497-429b-9599-c7baadb1ddbc",
- "alias": "forms",
- "description": "Username, password, otp and other auth forms.",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "0d08b35b-3aa9-4291-baf2-fd272113bdf5",
- "alias": "registration",
- "description": "registration flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-page-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "flowAlias": "registration form",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "85945bc3-661b-4c0b-bb38-415e71c858d6",
- "alias": "registration form",
- "description": "registration form",
- "providerId": "form-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-user-creation",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-profile-action",
- "requirement": "REQUIRED",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-password-action",
- "requirement": "REQUIRED",
- "priority": 50,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-recaptcha-action",
- "requirement": "DISABLED",
- "priority": 60,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "0603f7b0-5da7-4f06-a5b9-f74b996e6e4a",
- "alias": "reset credentials",
- "description": "Reset credentials for a user if they forgot their password or something",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "reset-credentials-choose-user",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-credential-email",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-password",
- "requirement": "REQUIRED",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-otp",
- "requirement": "OPTIONAL",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "2053759f-2888-488d-bde2-17470e18973d",
- "alias": "saml ecp",
- "description": "SAML ECP Profile Authentication Flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "http-basic-authenticator",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- }
- ],
- "authenticatorConfig": [
- {
- "id": "e8986891-5123-489c-8693-062442567069",
- "alias": "create unique user config",
- "config": {
- "require.password.update.after.registration": "false"
- }
- },
- {
- "id": "6ad5443c-6b33-4507-a339-e0399c3e5a59",
- "alias": "review profile config",
- "config": {
- "update.profile.on.first.login": "missing"
- }
- }
- ],
- "requiredActions": [
- {
- "alias": "CONFIGURE_TOTP",
- "name": "Configure OTP",
- "providerId": "CONFIGURE_TOTP",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "UPDATE_PASSWORD",
- "name": "Update Password",
- "providerId": "UPDATE_PASSWORD",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "UPDATE_PROFILE",
- "name": "Update Profile",
- "providerId": "UPDATE_PROFILE",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "VERIFY_EMAIL",
- "name": "Verify Email",
- "providerId": "VERIFY_EMAIL",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "terms_and_conditions",
- "name": "Terms and Conditions",
- "providerId": "terms_and_conditions",
- "enabled": false,
- "defaultAction": false,
- "config": {}
- }
- ],
- "browserFlow": "browser",
- "registrationFlow": "registration",
- "directGrantFlow": "direct grant",
- "resetCredentialsFlow": "reset credentials",
- "clientAuthenticationFlow": "clients",
- "attributes": {
- "_browser_header.xFrameOptions": "SAMEORIGIN",
- "failureFactor": "30",
- "quickLoginCheckMilliSeconds": "1000",
- "maxDeltaTimeSeconds": "43200",
- "_browser_header.xContentTypeOptions": "nosniff",
- "bruteForceProtected": "false",
- "maxFailureWaitSeconds": "900",
- "_browser_header.contentSecurityPolicy": "frame-src 'self'",
- "minimumQuickLoginWaitSeconds": "60",
- "waitIncrementSeconds": "60"
- },
- "keycloakVersion": "2.2.1.Final"
- },
- {
- "id": "master",
- "realm": "master",
- "displayName": "Keycloak",
- "displayNameHtml": "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
- "notBefore": 0,
- "revokeRefreshToken": false,
- "accessTokenLifespan": 60,
- "accessTokenLifespanForImplicitFlow": 900,
- "ssoSessionIdleTimeout": 1800,
- "ssoSessionMaxLifespan": 36000,
- "offlineSessionIdleTimeout": 2592000,
- "accessCodeLifespan": 60,
- "accessCodeLifespanUserAction": 300,
- "accessCodeLifespanLogin": 1800,
- "enabled": true,
- "sslRequired": "external",
- "registrationAllowed": false,
- "registrationEmailAsUsername": false,
- "rememberMe": false,
- "verifyEmail": false,
- "resetPasswordAllowed": false,
- "editUsernameAllowed": false,
- "bruteForceProtected": false,
- "maxFailureWaitSeconds": 900,
- "minimumQuickLoginWaitSeconds": 60,
- "waitIncrementSeconds": 60,
- "quickLoginCheckMilliSeconds": 1000,
- "maxDeltaTimeSeconds": 43200,
- "failureFactor": 30,
- "privateKey": "MIIEowIBAAKCAQEAiU54OXoCbHy0L0gHn1yasctcnKHRU1pHFIJnWvaI7rClJydet9dDJaiYXOxMKseiBm3eYznfN3cPyU8udYmRnMuKjiocZ77LT2IEttAjXb6Ggazx7loriFHRy0IOJeX4KxXhAPWmxqa3mkFNfLBEvFqVaBgUDHQ60cmnPvNSHYudBTW9K80s8nvmP2pso7HTwWJ1+Xatj1Ey/gTmB3CXlyqBegGWC9TeuErEYpYhdh+11TVWasgMBZyUCtL3NRPaBuhaPg1LpW8lWGk05nS+YM6dvTk3Mppv+z2RygEpxyO09oT3b4G+Zfwit1STqn0AvDTGzINdoKcNtFScV0j8TwIDAQABAoIBAHcbPKsPLZ8SJfOF1iblW8OzFulAbaaSf2pJHIMJrQrw7LKkMkPjVXoLX+/rgr7xYZmWIP2OLBWfEHCeYTzQUyHiZpSf7vgHx7Fa45/5uVQOe/ttHIiYa37bCtP4vvEdJkOpvP7qGPvljwsebqsk9Ns28LfVez66bHOjK5Mt2yOIulbTeEs7ch//h39YwKJv96vc+CHbV2O6qoOxZessO6y+287cOBvbFXmS2GaGle5Nx/EwncBNS4b7czoetmm70+9ht3yX+kxaP311YUT31KQjuaJt275kOiKsrXr27PvgO++bsIyGuSzqyS7G7fmxF2zUyphEqEpalyDGMKMnrAECgYEA1fCgFox03rPDjm0MhW/ThoS2Ld27sbWQ6reS+PBMdUTJZVZIU1D2//h6VXDnlddhk6avKjA4smdy1aDKzmjz3pt9AKn+kgkXqtTC2fD3wp+fC9hND0z+rQPGe/Gk7ZUnTdsqnfyowxr+woIgzdnRukOUrG+xQiP3RUUT7tt6NQECgYEApEz2xvgqMm+9/f/YxjLdsFUfLqc4WlafB863stYEVqlCYy5ujyo0VQ0ahKSKJkLDnf52+aMUqPOpwaGePpu3O6VkvpcKfPY2MUlZW7/6Sa9et9hxNkdTS7Gui2d1ELpaCBe1Bc62sk8EA01iHXE1PpvyUqDWrhNh+NrDICA9oU8CgYBgGDYACtTP11TmW2r9YK5VRLUDww30k4ZlN1GnyV++aMhBYVEZQ0u+y+A/EnijIFwu0vbo70H4OGknNZMCxbeMbLDoJHM5KyZbUDe5ZvgSjloFGwH59m6KTiDQOUkIgi9mVCQ/VGaFRFHcElEjxUvj60kTbxPijn8ZuR5r8l9hAQKBgQCQ9jL5pHWeoIayN20smi6M6N2lTPbkhe60dcgQatHTIG2pkosLl8IqlHAkPgSB84AiwyR351JQKwRJCm7TcJI/dxMnMZ6YWKfB3qSP1hdfsfJRJQ/mQxIUBAYrizF3e+P5peka4aLCOgMhYsJBlePThMZN7wja99EGPwXQL4IQ8wKBgB8Nis1lQK6Z30GCp9u4dYleGfEP71Lwqvk/eJb89/uz0fjF9CTpJMULFc+nA5u4yHP3LFnRg3zCU6aEwfwUyk4GH9lWGV/qIAisQtgrCEraVe4qxz0DVE59C7qjO26IhU2U66TEzPAqvQ3zqey+woDn/cz/JMWK1vpcSk+TKn3K",
- "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiU54OXoCbHy0L0gHn1yasctcnKHRU1pHFIJnWvaI7rClJydet9dDJaiYXOxMKseiBm3eYznfN3cPyU8udYmRnMuKjiocZ77LT2IEttAjXb6Ggazx7loriFHRy0IOJeX4KxXhAPWmxqa3mkFNfLBEvFqVaBgUDHQ60cmnPvNSHYudBTW9K80s8nvmP2pso7HTwWJ1+Xatj1Ey/gTmB3CXlyqBegGWC9TeuErEYpYhdh+11TVWasgMBZyUCtL3NRPaBuhaPg1LpW8lWGk05nS+YM6dvTk3Mppv+z2RygEpxyO09oT3b4G+Zfwit1STqn0AvDTGzINdoKcNtFScV0j8TwIDAQAB",
- "certificate": "MIICmzCCAYMCBgFXt/Tg9TANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMTYxMDEyMDgxMjQxWhcNMjYxMDEyMDgxNDIxWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJTng5egJsfLQvSAefXJqxy1ycodFTWkcUgmda9ojusKUnJ16310MlqJhc7Ewqx6IGbd5jOd83dw/JTy51iZGcy4qOKhxnvstPYgS20CNdvoaBrPHuWiuIUdHLQg4l5fgrFeEA9abGpreaQU18sES8WpVoGBQMdDrRyac+81Idi50FNb0rzSzye+Y/amyjsdPBYnX5dq2PUTL+BOYHcJeXKoF6AZYL1N64SsRiliF2H7XVNVZqyAwFnJQK0vc1E9oG6Fo+DUulbyVYaTTmdL5gzp29OTcymm/7PZHKASnHI7T2hPdvgb5l/CK3VJOqfQC8NMbMg12gpw20VJxXSPxPAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAC54wFHL8tmrksq4OzatzNUM+R+3Hu/VXX3T44dwg0EvXzGW45sME+gKCuleU1PabIrr6oFm0bBMTdxgE2hbLWpYbU3OcsjArpCeCsOlxrAkqhVQN161J+tp77JkDMgArFdwe3wh5bhvLaOZSt6Fsq+oo16CXG1obe1feyaK3+sU3YuDUIHE01UYtvwtfDsYBC+VDyTdNDbB15WcdRoGljJY/JiT0JHdmAfq8qdGDuxGocIV0lSB8bO5JwF/WCmKqMrnh5j1NfGcE1g26Hbz2RmDs17X0K10Okzs/qz1YZqDjPVYiU//VFQQro71/D35dPOJv8mQMjhjNaXScL44h7w=",
- "codeSecret": "4c59c2db-d9c3-4023-8cd5-8808fe854e98",
- "roles": {
- "realm": [
- {
- "id": "40dd3051-9581-479d-9ae0-80abd28b3f94",
- "name": "create-realm",
- "description": "${role_create-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false,
- "containerId": "master"
- },
- {
- "id": "b4693527-02c6-4e26-b1e2-b2249138304c",
- "name": "master-test-realm-role",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false,
- "containerId": "master"
- },
- {
- "id": "5e030453-7094-42a5-8fd2-ce88c46c1172",
- "name": "admin",
- "description": "${role_admin}",
- "scopeParamRequired": false,
- "composite": true,
- "composites": {
- "realm": [
- "create-realm"
- ],
- "client": {
- "Migration-realm": [
- "view-users",
- "manage-users",
- "view-clients",
- "manage-identity-providers",
- "manage-clients",
- "impersonation",
- "create-client",
- "manage-events",
- "manage-realm",
- "view-realm",
- "view-authorization",
- "view-events",
- "manage-authorization",
- "view-identity-providers"
- ],
- "master-realm": [
- "view-identity-providers",
- "manage-realm",
- "create-client",
- "manage-users",
- "impersonation",
- "view-clients",
- "manage-authorization",
- "view-realm",
- "manage-events",
- "view-authorization",
- "view-users",
- "manage-identity-providers",
- "view-events",
- "manage-clients"
- ]
- }
- },
- "clientRole": false,
- "containerId": "master"
- },
- {
- "id": "311339f9-a82d-4960-a06a-63775649ac50",
- "name": "uma_authorization",
- "description": "${role_uma_authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": false,
- "containerId": "master"
- },
- {
- "id": "dc09cba8-f24d-4731-9169-47a951e519eb",
- "name": "offline_access",
- "description": "${role_offline-access}",
- "scopeParamRequired": true,
- "composite": false,
- "clientRole": false,
- "containerId": "master"
- }
- ],
- "client": {
- "security-admin-console": [],
- "master-test-client": [
- {
- "id": "9c25e418-2415-43f1-90ef-1627272e22ef",
- "name": "master-test-client-role",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "6268e266-346b-46ba-8408-fe17b5792b10"
- }
- ],
- "admin-cli": [],
- "Migration-realm": [
- {
- "id": "4bd2a237-8e0e-4909-b8d5-f1635d442f3c",
- "name": "manage-events",
- "description": "${role_manage-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "0b9bb67b-16a3-4490-bd74-bf0aad1c43df",
- "name": "manage-realm",
- "description": "${role_manage-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "2038d832-6869-4bdd-94d7-abb605ec117b",
- "name": "view-realm",
- "description": "${role_view-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "85bcb1ac-257f-4d95-93e3-7f905c91bda0",
- "name": "view-authorization",
- "description": "${role_view-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "9c31faa8-e91d-4f71-ba5e-0cdb309a6c1b",
- "name": "view-events",
- "description": "${role_view-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "b7e97e07-c666-4e55-8c2b-127013fb70b2",
- "name": "manage-authorization",
- "description": "${role_manage-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "2567bcf2-532a-4950-95ec-18a8e993cbe8",
- "name": "view-users",
- "description": "${role_view-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "b3d7e97c-e6fe-418f-a354-7ad0c63efe72",
- "name": "manage-users",
- "description": "${role_manage-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "4881d187-699e-4130-9ca7-7afd71b7132f",
- "name": "view-clients",
- "description": "${role_view-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "c22bb7bf-9a27-40e4-af54-f452a17eb532",
- "name": "manage-identity-providers",
- "description": "${role_manage-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "f694e360-1635-479e-b4d6-e71a8a615ab8",
- "name": "view-identity-providers",
- "description": "${role_view-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "b2f38b33-aad3-4086-8c23-dafee15439cb",
- "name": "manage-clients",
- "description": "${role_manage-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "68b32df6-687f-4dd2-a93e-59f807cb3a4c",
- "name": "impersonation",
- "description": "${role_impersonation}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- },
- {
- "id": "500cae23-30a8-4221-96ca-1b4d15adae62",
- "name": "create-client",
- "description": "${role_create-client}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "c3aca840-5187-406e-9b1a-b62a57eb371a"
- }
- ],
- "broker": [
- {
- "id": "fefd0452-1eb5-40f6-aaec-b65fe38ae9b9",
- "name": "read-token",
- "description": "${role_read-token}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "5bcab424-560b-4653-b490-b03db075ecda"
- }
- ],
- "master-realm": [
- {
- "id": "c0303a3e-0663-4346-8321-85ebe587c0df",
- "name": "view-events",
- "description": "${role_view-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "08e2c729-09ee-42e0-8106-1a712f0f5d59",
- "name": "view-identity-providers",
- "description": "${role_view-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "0c339131-888a-4e00-a999-b2ac5cc8f891",
- "name": "manage-realm",
- "description": "${role_manage-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "3310eabb-f4d5-40fd-9aee-84c658f3c66f",
- "name": "create-client",
- "description": "${role_create-client}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "e6217299-9180-4be5-83ec-1f92645fbf3e",
- "name": "manage-users",
- "description": "${role_manage-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "4aeeab55-7859-4fbb-8f98-fb20919c98b4",
- "name": "impersonation",
- "description": "${role_impersonation}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "1f8f140a-1574-4ee8-9b91-360b2ae76e1b",
- "name": "view-clients",
- "description": "${role_view-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "181269dc-bfec-47d9-9946-6ebb9bbe36d6",
- "name": "manage-authorization",
- "description": "${role_manage-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "1d3757e9-167e-406c-93e6-5d30e9b819de",
- "name": "view-realm",
- "description": "${role_view-realm}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "abb6146d-1cd0-4d03-b74f-f448d8675409",
- "name": "manage-events",
- "description": "${role_manage-events}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "61486848-4bad-4ba2-bc46-bfae4a0a889f",
- "name": "view-authorization",
- "description": "${role_view-authorization}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "e2fc9a91-9415-41f9-b1cd-2f9456edb53e",
- "name": "manage-clients",
- "description": "${role_manage-clients}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "85131bab-8020-474f-bb70-76e78886df2b",
- "name": "view-users",
- "description": "${role_view-users}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- },
- {
- "id": "e8d6d361-b58a-4739-8747-687e5b1628e8",
- "name": "manage-identity-providers",
- "description": "${role_manage-identity-providers}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "470a14ef-efb5-4686-85a0-0738edd1f8d3"
- }
- ],
- "account": [
- {
- "id": "d2bf38f4-09fe-473a-b33f-18c1ff674705",
- "name": "manage-account",
- "description": "${role_manage-account}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "08a0990d-8288-4ba7-ba1e-0828cd1e002a"
- },
- {
- "id": "2f57d1ae-d6ca-488b-9395-ddf3f80e7c9d",
- "name": "view-profile",
- "description": "${role_view-profile}",
- "scopeParamRequired": false,
- "composite": false,
- "clientRole": true,
- "containerId": "08a0990d-8288-4ba7-ba1e-0828cd1e002a"
- }
- ]
- }
- },
- "groups": [
- {
- "id": "e6a9423c-2140-4c31-ba18-dd517b2b900a",
- "name": "master-test-group",
- "path": "/master-test-group",
- "attributes": {},
- "realmRoles": [],
- "clientRoles": {},
- "subGroups": []
- }
- ],
- "defaultRoles": [
- "offline_access",
- "uma_authorization"
- ],
- "requiredCredentials": [
- "password"
- ],
- "passwordPolicy": "hashIterations(20000)",
- "otpPolicyType": "totp",
- "otpPolicyAlgorithm": "HmacSHA1",
- "otpPolicyInitialCounter": 0,
- "otpPolicyDigits": 6,
- "otpPolicyLookAheadWindow": 1,
- "otpPolicyPeriod": 30,
- "users": [
- {
- "id": "c345ea0f-1c90-4a45-9b2f-96a381ca5a5b",
- "createdTimestamp": 1476265539362,
- "username": "admin",
- "enabled": true,
- "totp": false,
- "emailVerified": false,
- "credentials": [
- {
- "type": "password",
- "hashedSaltedValue": "YwCkHJ6u5ZROE/WkQgI6NHvg06bkbOy5eaz8M9fnLDTajjZqQfZELI8NmrQecCPXY8/GEI9jN1gL/5Y3yulIVA==",
- "salt": "MLKqip78LpUnPDBsNDAf8g==",
- "hashIterations": 20000,
- "counter": 0,
- "algorithm": "pbkdf2",
- "digits": 0,
- "createdDate": 1476265539000
- }
- ],
- "requiredActions": [],
- "realmRoles": [
- "admin",
- "uma_authorization",
- "offline_access"
- ],
- "clientRoles": {
- "account": [
- "manage-account",
- "view-profile"
- ]
- },
- "groups": []
- },
- {
- "id": "f9d17688-5a5f-40f2-829b-4444ede51f6f",
- "createdTimestamp": 1476265646817,
- "username": "master-test-user",
- "enabled": true,
- "totp": false,
- "emailVerified": false,
- "credentials": [],
- "requiredActions": [],
- "realmRoles": [
- "uma_authorization",
- "offline_access"
- ],
- "clientRoles": {
- "account": [
- "manage-account",
- "view-profile"
- ]
- },
- "groups": [
- "/master-test-group"
- ]
- }
- ],
- "scopeMappings": [
- {
- "client": "admin-cli",
- "roles": [
- "admin"
- ]
- },
- {
- "client": "security-admin-console",
- "roles": [
- "admin"
- ]
- }
- ],
- "clients": [
- {
- "id": "c3aca840-5187-406e-9b1a-b62a57eb371a",
- "clientId": "Migration-realm",
- "name": "Migration Realm",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "29958e6c-6f44-47a6-9810-770ea90b7387",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": true,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "d009ceb4-cb36-4abe-8425-e6df2737e627",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "24981db4-6740-4e08-a505-3aabe8e350c3",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "9ca7f1b4-170d-4d75-a94b-26511318bf2c",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "41482c5e-6c4c-4618-b819-bcb6e693caee",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "df1d77fa-2b6c-49fd-9785-2ee51ff937fd",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "5e90ad8d-98c0-4cc1-a74e-933cb77e82a6",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "08a0990d-8288-4ba7-ba1e-0828cd1e002a",
- "clientId": "account",
- "name": "${client_account}",
- "baseUrl": "/auth/realms/master/account",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "532d4ec6-0ff4-448e-bdfc-11b87efb50d3",
- "defaultRoles": [
- "view-profile",
- "manage-account"
- ],
- "redirectUris": [
- "/auth/realms/master/account/*"
- ],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "bfc0fe7c-1bdb-4d51-8cbb-93f3923683c8",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "6f500b7d-f16a-410f-a567-d4f38fc45c5e",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "b37bfe8a-94de-4893-b86e-b642c267d72b",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "7abb3444-776a-4537-928a-e1caf83c6df8",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "01314df4-5726-4855-b71d-aaedcee9604b",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "4a16b178-40ef-4a88-94e8-330fe92405d2",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "9da2f23b-767b-4d99-8d24-a1cab6afe448",
- "clientId": "admin-cli",
- "name": "${client_admin-cli}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "3b37796a-29ee-46b8-b606-12ea19d40097",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": false,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "1631e30c-79b1-4a24-bbd7-a2833100d140",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7a19f140-f951-4505-b200-46b41ccdeed3",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "d6b5b848-2575-4de6-b2cd-cf692b0daa22",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "94a1d7ad-b103-491e-9b76-65f763420d0a",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "ed2d7ce3-3f24-4412-8ee0-91a8ab22913a",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "c342307c-9fb2-4e7d-9bf7-a18985227483",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "5bcab424-560b-4653-b490-b03db075ecda",
- "clientId": "broker",
- "name": "${client_broker}",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "6613ea12-47d2-4e07-bcae-329211df19c9",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "eebc4c71-63f9-4c51-abb9-0577f1188399",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "73bbb61d-f87a-4d52-a0ce-3f675b79d808",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "3172c3dd-7253-4546-9ff0-735f4635a5f3",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "895bf3d3-21dc-478c-9aad-dedc148518a3",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "40e1c333-168c-444b-9ae5-5d4fd9f07a82",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "974e0506-401d-4ff0-a43c-6f9d63920473",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "470a14ef-efb5-4686-85a0-0738edd1f8d3",
- "clientId": "master-realm",
- "name": "master Realm",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "70bb98e1-51ed-4ebb-a103-1e2cad38a292",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": true,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": false,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "b9f0a1d5-9a56-4c42-938b-54b9aae180e4",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "629ba061-ee90-4893-9a3c-6ebb1cb8586f",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- },
- {
- "id": "e02314bb-f3de-4f72-874c-2ccb30727e52",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "c82eaace-135c-4373-ac99-d09469bc1b12",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "a82fe8ca-df8d-4ad7-bbfd-c5f0adfd8cd2",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "44ae3204-8f77-4a7d-ac7f-c44bafed3ad2",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "6268e266-346b-46ba-8408-fe17b5792b10",
- "clientId": "master-test-client",
- "name": "master-test-client",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "271c50a7-6a20-4a27-bb94-97136ffb1539",
- "redirectUris": [],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {},
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": -1,
- "protocolMappers": [
- {
- "id": "191b5693-2fdd-4029-8657-681facc51dfb",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "079b1dba-1ac0-4d3d-94b7-d8468dc55962",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "1fc5cdff-d1ba-4492-83df-f81d3820c31a",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "8a443f85-23c0-4ee6-9e31-4b5ad571aa94",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7b5f4689-ede2-427b-b8dc-289791ac6cad",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "b1af3b5e-fff1-41c2-b091-0c35a6c84793",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- },
- {
- "id": "a27cd9f4-e9f3-45d9-aef1-0509a8337de0",
- "clientId": "security-admin-console",
- "name": "${client_security-admin-console}",
- "baseUrl": "/auth/admin/master/console/index.html",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "f7f2c609-8902-4db2-9350-685b0423457b",
- "redirectUris": [
- "/auth/admin/master/console/*"
- ],
- "webOrigins": [],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": false,
- "serviceAccountsEnabled": false,
- "publicClient": true,
- "frontchannelLogout": false,
- "attributes": {},
- "fullScopeAllowed": false,
- "nodeReRegistrationTimeout": 0,
- "protocolMappers": [
- {
- "id": "a7dd5e41-4d47-41fe-b5ad-33e1ad801f31",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${givenName}",
- "config": {
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "4c89dd7c-d865-4557-aa52-d25e83c70789",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${familyName}",
- "config": {
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "d4fa50be-3a2f-4d4c-9123-a5d99b8315e5",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- },
- {
- "id": "8bf5feae-36bd-49f5-8a2e-19093ee92a29",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${email}",
- "config": {
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "2b8281b5-e2a8-4868-92f8-76097648f328",
- "name": "locale",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "consentText": "${locale}",
- "config": {
- "user.attribute": "locale",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "locale",
- "jsonType.label": "String"
- }
- },
- {
- "id": "20551202-834b-4f9d-9582-6f27d58b604d",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": true,
- "consentText": "${username}",
- "config": {
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "f205e545-5b2d-4436-b9c8-88a07de1ea7d",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": true,
- "consentText": "${fullName}",
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true"
- }
- }
- ],
- "useTemplateConfig": false,
- "useTemplateScope": false,
- "useTemplateMappers": false
- }
- ],
- "clientTemplates": [],
- "browserSecurityHeaders": {
- "xContentTypeOptions": "nosniff",
- "xFrameOptions": "SAMEORIGIN",
- "contentSecurityPolicy": "frame-src 'self'"
- },
- "smtpServer": {},
- "eventsEnabled": false,
- "eventsListeners": [
- "jboss-logging"
- ],
- "enabledEventTypes": [],
- "adminEventsEnabled": false,
- "adminEventsDetailsEnabled": false,
- "components": {},
- "internationalizationEnabled": false,
- "supportedLocales": [],
- "authenticationFlows": [
- {
- "id": "7823af6c-d339-4b0c-a786-83d7dbba3052",
- "alias": "Handle Existing Account",
- "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-confirm-link",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "idp-email-verification",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "Verify Existing Account by Re-authentication",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "506407b8-40db-4e67-99f7-4d21549a72ea",
- "alias": "Verify Existing Account by Re-authentication",
- "description": "Reauthentication of existing account",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "idp-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "f5ab7c19-2940-4b1d-8ce3-cca8014501a3",
- "alias": "browser",
- "description": "browser based authentication",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-cookie",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-spnego",
- "requirement": "DISABLED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "identity-provider-redirector",
- "requirement": "ALTERNATIVE",
- "priority": 25,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "forms",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "a0dca221-6b16-447c-960b-50d0231a579b",
- "alias": "clients",
- "description": "Base authentication for clients",
- "providerId": "client-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "client-secret",
- "requirement": "ALTERNATIVE",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-jwt",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "2fc9e6fe-23e4-4d5d-8de7-7df4352cc92f",
- "alias": "direct grant",
- "description": "OpenID Connect Resource Owner Grant",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "direct-grant-validate-username",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-password",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "direct-grant-validate-otp",
- "requirement": "OPTIONAL",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "8e4c82e6-1981-4877-b97a-4ef5c1981d05",
- "alias": "first broker login",
- "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticatorConfig": "review profile config",
- "authenticator": "idp-review-profile",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticatorConfig": "create unique user config",
- "authenticator": "idp-create-user-if-unique",
- "requirement": "ALTERNATIVE",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "flowAlias": "Handle Existing Account",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "10f78331-e0d5-4a99-be02-7fc1f5d31215",
- "alias": "forms",
- "description": "Username, password, otp and other auth forms.",
- "providerId": "basic-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "auth-username-password-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "f6a0beb4-7fd1-4c83-afe9-44518f45ed7b",
- "alias": "registration",
- "description": "registration flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-page-form",
- "requirement": "REQUIRED",
- "priority": 10,
- "flowAlias": "registration form",
- "userSetupAllowed": false,
- "autheticatorFlow": true
- }
- ]
- },
- {
- "id": "b4029db6-dc6e-44a5-b685-86e394ff7dfb",
- "alias": "registration form",
- "description": "registration form",
- "providerId": "form-flow",
- "topLevel": false,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "registration-user-creation",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-profile-action",
- "requirement": "REQUIRED",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-password-action",
- "requirement": "REQUIRED",
- "priority": 50,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "registration-recaptcha-action",
- "requirement": "DISABLED",
- "priority": 60,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "2758d06b-35da-43a7-83dc-ec02e5ffc1be",
- "alias": "reset credentials",
- "description": "Reset credentials for a user if they forgot their password or something",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "reset-credentials-choose-user",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-credential-email",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-password",
- "requirement": "REQUIRED",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "reset-otp",
- "requirement": "OPTIONAL",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "b1927d79-54d8-4b5f-a01a-f4d5be8d3769",
- "alias": "saml ecp",
- "description": "SAML ECP Profile Authentication Flow",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [
- {
- "authenticator": "http-basic-authenticator",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- }
- ],
- "authenticatorConfig": [
- {
- "id": "e40c22b1-546d-4df6-8798-dca761db8cf0",
- "alias": "create unique user config",
- "config": {
- "require.password.update.after.registration": "false"
- }
- },
- {
- "id": "bacdeb1b-bfc5-4adc-9a3e-798d8dd6a6da",
- "alias": "review profile config",
- "config": {
- "update.profile.on.first.login": "missing"
- }
- }
- ],
- "requiredActions": [
- {
- "alias": "CONFIGURE_TOTP",
- "name": "Configure OTP",
- "providerId": "CONFIGURE_TOTP",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "UPDATE_PASSWORD",
- "name": "Update Password",
- "providerId": "UPDATE_PASSWORD",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "UPDATE_PROFILE",
- "name": "Update Profile",
- "providerId": "UPDATE_PROFILE",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "VERIFY_EMAIL",
- "name": "Verify Email",
- "providerId": "VERIFY_EMAIL",
- "enabled": true,
- "defaultAction": false,
- "config": {}
- },
- {
- "alias": "terms_and_conditions",
- "name": "Terms and Conditions",
- "providerId": "terms_and_conditions",
- "enabled": false,
- "defaultAction": false,
- "config": {}
- }
- ],
- "browserFlow": "browser",
- "registrationFlow": "registration",
- "directGrantFlow": "direct grant",
- "resetCredentialsFlow": "reset credentials",
- "clientAuthenticationFlow": "clients",
- "attributes": {
- "_browser_header.xFrameOptions": "SAMEORIGIN",
- "failureFactor": "30",
- "quickLoginCheckMilliSeconds": "1000",
- "maxDeltaTimeSeconds": "43200",
- "displayName": "Keycloak",
- "_browser_header.xContentTypeOptions": "nosniff",
- "bruteForceProtected": "false",
- "maxFailureWaitSeconds": "900",
- "_browser_header.contentSecurityPolicy": "frame-src 'self'",
- "minimumQuickLoginWaitSeconds": "60",
- "displayNameHtml": "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
- "waitIncrementSeconds": "60"
- },
- "keycloakVersion": "2.2.1.Final"
- },
{
"id": "authorization",
"realm": "authorization",
@@ -5550,4 +616,3 @@
},
"keycloakVersion": "2.2.1.Final"
}
-]
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json
index 98fa9a6..6a090ce 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json
@@ -331,6 +331,17 @@
],
"adminUrl": "http://localhost:8180/namedapp/base/admin",
"secret": "password"
+ },
+ {
+ "clientId": "var-named-test-app",
+ "name": "Test App Named - ${client_account}",
+ "enabled": true,
+ "baseUrl": "http://localhost:8180/varnamedapp/base",
+ "redirectUris": [
+ "http://localhost:8180/varnamedapp/base/*"
+ ],
+ "adminUrl": "http://localhost:8180/varnamedapp/base/admin",
+ "secret": "password"
}
],
"roles" : {
diff --git a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java
index 58d4f71..064d46e 100755
--- a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java
+++ b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/JettySamlTest.java
@@ -111,8 +111,12 @@ public class JettySamlTest {
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
diff --git a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java
index 58d4f71..064d46e 100755
--- a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java
+++ b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/JettySamlTest.java
@@ -111,8 +111,12 @@ public class JettySamlTest {
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
diff --git a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java
index 7f1ec98..f1e72a4 100755
--- a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java
+++ b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/JettySamlTest.java
@@ -111,8 +111,12 @@ public class JettySamlTest {
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
diff --git a/testsuite/jetty/jetty93/src/test/java/org/keycloak/testsuite/JettySamlTest.java b/testsuite/jetty/jetty93/src/test/java/org/keycloak/testsuite/JettySamlTest.java
index 7f1ec98..f1e72a4 100644
--- a/testsuite/jetty/jetty93/src/test/java/org/keycloak/testsuite/JettySamlTest.java
+++ b/testsuite/jetty/jetty93/src/test/java/org/keycloak/testsuite/JettySamlTest.java
@@ -111,8 +111,12 @@ public class JettySamlTest {
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
index d306ede..dc3bd09 100755
--- a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
+++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
@@ -120,8 +120,12 @@ public class TomcatSamlTest {
}
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
diff --git a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
index 0eb7b94..b4a6d1c 100755
--- a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
+++ b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
@@ -98,8 +98,12 @@ public class TomcatSamlTest {
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
diff --git a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
index b347f48..1456496 100755
--- a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
+++ b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
@@ -99,8 +99,12 @@ public class TomcatSamlTest {
@Test
- public void testErrorHandling() throws Exception {
- testStrategy.testErrorHandling();
+ public void testErrorHandlingSigned() throws Exception {
+ testStrategy.testErrorHandlingSigned();
+ }
+ @Test
+ public void testErrorHandlingUnsigned() throws Exception {
+ testStrategy.testErrorHandlingUnsigned();
}
@Test
diff --git a/themes/src/main/resources/theme/base/account/messages/messages_de.properties b/themes/src/main/resources/theme/base/account/messages/messages_de.properties
index f9d27e9..f91c8d9 100644
--- a/themes/src/main/resources/theme/base/account/messages/messages_de.properties
+++ b/themes/src/main/resources/theme/base/account/messages/messages_de.properties
@@ -50,6 +50,7 @@ role_manage-clients=Clients verwalten
role_manage-events=Events verwalten
role_view-profile=Profile ansehen
role_manage-account=Profile verwalten
+client_account=Konto
requiredFields=Erforderliche Felder
allFieldsRequired=Alle Felder sind Erforderlich
diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
index b6d285b..d047b77 100644
--- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
+++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -504,7 +504,7 @@ identity-provider.jwks-url.tooltip=URL where identity provider keys in JWK forma
validating-public-key=Validating Public Key
identity-provider.validating-public-key.tooltip=The public key in PEM format that must be used to verify external IDP signatures.
validating-public-key-id=Validating Public Key Id
-identity-provider.validating-public-key-id.tooltip=Explicit ID of the validating public key given above if the key ID. Leave unset if the external IDP is Keycloak or uses the same mechanism to determine key ID.
+identity-provider.validating-public-key-id.tooltip=Explicit ID of the validating public key given above if the key ID. Leave blank if the key above should be used always, regardless of key ID specified by external IDP; set it if the key should only be used for verifying if key ID from external IDP matches.
import-external-idp-config=Import External IDP Config
import-external-idp-config.tooltip=Allows you to load external IDP metadata from a config file or to download it from a URL.
import-from-url=Import from URL
diff --git a/themes/src/main/resources/theme/keycloak/login/resources/css/login.css b/themes/src/main/resources/theme/keycloak/login/resources/css/login.css
index bbf08af..6ca81ad 100644
--- a/themes/src/main/resources/theme/keycloak/login/resources/css/login.css
+++ b/themes/src/main/resources/theme/keycloak/login/resources/css/login.css
@@ -253,10 +253,13 @@ ol#kc-totp-settings li:first-of-type {
#kc-container-wrapper {
position: absolute;
width: 100%;
+ margin-top: 50px;
}
#kc-logo-wrapper {
- margin-left: auto;
+ position: absolute;
+ top: 50px;
+ right: 50px;
}
.login-pf .container {
@@ -319,13 +322,14 @@ ol#kc-totp-settings li:first-of-type {
}
}
-@media (min-height: 621px) {
+@media (min-height: 646px) {
#kc-container-wrapper {
bottom: 12%;
}
}
-@media (max-height: 620px) {
+@media (max-height: 645px) {
#kc-container-wrapper {
+ top: 20%;
}
}