diff --git a/repository-dependencies/pom.xml b/repository-dependencies/pom.xml
index 998bb60..7fcc35d 100644
--- a/repository-dependencies/pom.xml
+++ b/repository-dependencies/pom.xml
@@ -33,6 +33,11 @@
org.keycloak
keycloak-adapter-core
+
+
+ com.sun.activation
+ *
+
org.bouncycastle
*
@@ -48,6 +53,11 @@
org.keycloak
keycloak-servlet-adapter-spi
+
+
+ com.sun.activation
+ *
+
org.bouncycastle
*
@@ -56,6 +66,11 @@
com.fasterxml.jackson.core
*
+
+
+ org.apache.httpcomponents
+ httpcomponents-client
+
@@ -63,6 +78,11 @@
org.keycloak
keycloak-servlet-filter-adapter
+
+
+ com.sun.activation
+ *
+
org.bouncycastle
*
diff --git a/repository/src/main/config/log4j.properties b/repository/src/main/config/log4j.properties
index 3733c5c..d64e80b 100644
--- a/repository/src/main/config/log4j.properties
+++ b/repository/src/main/config/log4j.properties
@@ -1,2 +1,4 @@
log4j.logger.${project.artifactId}=INFO
-log4j.logger.${project.artifactId}.deps=ERROR
\ No newline at end of file
+log4j.logger.${project.artifactId}.deps=ERROR
+log4j.logger.${project.artifactId}.deps.keycloak=ERROR
+log4j.logger.${project.artifactId}.deps.jboss=ERROR
\ No newline at end of file
diff --git a/repository/src/main/config/module-context.xml b/repository/src/main/config/module-context.xml
index 1daa95d..f5d03ed 100644
--- a/repository/src/main/config/module-context.xml
+++ b/repository/src/main/config/module-context.xml
@@ -75,7 +75,7 @@
-
+
diff --git a/repository/src/main/globalConfig/subsystems/Authentication/keycloak/keycloak-authentication-context.xml b/repository/src/main/globalConfig/subsystems/Authentication/keycloak/keycloak-authentication-context.xml
index c26bc00..dbbdcf2 100644
--- a/repository/src/main/globalConfig/subsystems/Authentication/keycloak/keycloak-authentication-context.xml
+++ b/repository/src/main/globalConfig/subsystems/Authentication/keycloak/keycloak-authentication-context.xml
@@ -109,14 +109,21 @@
-
+
+
+
+
+
+
+
+
-
-
+
-
+
+
diff --git a/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakAuthenticationFilter.java b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakAuthenticationFilter.java
index bcac2f8..a34b470 100644
--- a/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakAuthenticationFilter.java
+++ b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakAuthenticationFilter.java
@@ -484,10 +484,6 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
final SessionUser sessionUser = this.createUserEnvironment(session, userId);
this.keycloakAuthenticationComponent.handleUserTokens(accessToken, keycloakSecurityContext.getIdToken(), true);
- // need different attribute name than default for integration with web scripts framework
- // default attribute name seems to be no longer used
- session.setAttribute(AuthenticationDriver.AUTHENTICATION_USER, sessionUser);
-
this.authenticationListener.userAuthenticated(new KeycloakCredentials(accessToken));
// store tokens in cache as well for ticket validation
@@ -529,6 +525,41 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
chain.doFilter(requestWrapper, res);
}
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected SessionUser createUserEnvironment(final HttpSession session, final String userName) throws IOException, ServletException
+ {
+ final SessionUser sessionUser = super.createUserEnvironment(session, userName);
+
+ // ensure all common attribute names are mapped
+ // Alfresco is really inconsistent with these attribute names
+ session.setAttribute(AuthenticationDriver.AUTHENTICATION_USER, sessionUser);
+ session.setAttribute(BaseAuthenticationFilter.AUTHENTICATION_USER, sessionUser);
+
+ return sessionUser;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected SessionUser createUserEnvironment(final HttpSession session, final String userName, final String ticket,
+ final boolean externalAuth) throws IOException, ServletException
+ {
+ final SessionUser sessionUser = super.createUserEnvironment(session, userName, ticket, externalAuth);
+
+ // ensure all common attribute names are mapped
+ // Alfresco is really inconsistent with these attribute names
+ session.setAttribute(AuthenticationDriver.AUTHENTICATION_USER, sessionUser);
+ session.setAttribute(BaseAuthenticationFilter.AUTHENTICATION_USER, sessionUser);
+
+ return sessionUser;
+ }
+
/**
* Processes a failed authentication via Keycloak.
*
@@ -607,10 +638,6 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
LOGGER.trace("Skipping doFilter as filter is not active");
skip = true;
}
- else if (req.getAttribute(NO_AUTH_REQUIRED) != null)
- {
- LOGGER.trace("Skipping doFilter as filter higher up in chain determined authentication as not required");
- }
else if (servletRequestUri.matches(KEYCLOAK_ACTION_URL_PATTERN))
{
LOGGER.trace("Explicitly not skipping doFilter as Keycloak action URL is being called");
@@ -636,6 +663,14 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
else if (this.allowTicketLogon && this.checkForTicketParameter(context, req, res))
{
LOGGER.trace("Skipping doFilter as user was authenticated by ticket URL parameter");
+ skip = true;
+ }
+ // check no-auth flag (derived e.g. from checking if target web script requires authentication) only after all pre-emptive auth
+ // request details have been checked
+ else if (Boolean.TRUE.equals(req.getAttribute(NO_AUTH_REQUIRED)))
+ {
+ LOGGER.trace("Skipping doFilter as filter higher up in chain determined authentication as not required");
+ skip = true;
}
else if (sessionUser != null)
{
diff --git a/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakWebScriptCookieAuthenticationFilter.java b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakWebScriptCookieAuthenticationFilter.java
new file mode 100644
index 0000000..4168a8d
--- /dev/null
+++ b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakWebScriptCookieAuthenticationFilter.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019 - 2020 Acosix GmbH
+ *
+ * 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 de.acosix.alfresco.keycloak.repo.authentication;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
+
+import org.alfresco.repo.SessionUser;
+import org.alfresco.repo.webdav.auth.AuthenticationDriver;
+import org.alfresco.repo.webdav.auth.BaseAuthenticationFilter;
+import org.alfresco.web.app.servlet.WebscriptCookieAuthenticationFilter;
+
+/**
+ * This sub-class of the default web script cookie filter only exists to ensure the proper session attribute names are used for mapping the
+ * authenticated session user.
+ *
+ * @author Axel Faust
+ */
+public class KeycloakWebScriptCookieAuthenticationFilter extends WebscriptCookieAuthenticationFilter
+{
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected SessionUser createUserEnvironment(final HttpSession session, final String userName) throws IOException, ServletException
+ {
+ final SessionUser sessionUser = super.createUserEnvironment(session, userName);
+
+ // ensure all common attribute names are mapped
+ // Alfresco is really inconsistent with these attribute names
+ session.setAttribute(AuthenticationDriver.AUTHENTICATION_USER, sessionUser);
+ session.setAttribute(BaseAuthenticationFilter.AUTHENTICATION_USER, sessionUser);
+
+ return sessionUser;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected SessionUser createUserEnvironment(final HttpSession session, final String userName, final String ticket,
+ final boolean externalAuth) throws IOException, ServletException
+ {
+ final SessionUser sessionUser = super.createUserEnvironment(session, userName, ticket, externalAuth);
+
+ // ensure all common attribute names are mapped
+ // Alfresco is really inconsistent with these attribute names
+ session.setAttribute(AuthenticationDriver.AUTHENTICATION_USER, sessionUser);
+ session.setAttribute(BaseAuthenticationFilter.AUTHENTICATION_USER, sessionUser);
+
+ return sessionUser;
+ }
+}
diff --git a/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakWebScriptSSOAuthenticationFilter.java b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakWebScriptSSOAuthenticationFilter.java
new file mode 100644
index 0000000..fba39ce
--- /dev/null
+++ b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/authentication/KeycloakWebScriptSSOAuthenticationFilter.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2019 - 2020 Acosix GmbH
+ *
+ * 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 de.acosix.alfresco.keycloak.repo.authentication;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.alfresco.repo.management.subsystems.ActivateableBean;
+import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
+import org.alfresco.repo.webdav.auth.BaseAuthenticationFilter;
+import org.alfresco.util.PropertyCheck;
+import org.alfresco.web.app.servlet.WebScriptSSOAuthenticationFilter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.extensions.surf.util.URLDecoder;
+import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
+import org.springframework.extensions.webscripts.Match;
+import org.springframework.extensions.webscripts.RuntimeContainer;
+
+/**
+ * This web script SSO authentication filter class is used instead of {@link WebScriptSSOAuthenticationFilter default Alfresco filter} in
+ * order to properly handle unauthenticated and guest access, especially since the later is performed by Alfresco Share to load edition
+ * details and potentially other data needed for determining which customisations are active, even before a user has had a chance to
+ * authenticate.
+ *
+ * @author Axel Faust
+ */
+public class KeycloakWebScriptSSOAuthenticationFilter extends BaseAuthenticationFilter
+ implements DependencyInjectedFilter, InitializingBean, ActivateableBean
+{
+
+ // copied from WebScriptRequestImpl due to accessible constraints
+ private static final String ARG_GUEST = "guest";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(KeycloakWebScriptSSOAuthenticationFilter.class);
+
+ protected RuntimeContainer container;
+
+ protected boolean isActive = true;
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void afterPropertiesSet()
+ {
+ PropertyCheck.mandatory(this, "container", this.container);
+ }
+
+ /**
+ * @param container
+ * the container to set
+ */
+ public void setContainer(final RuntimeContainer container)
+ {
+ this.container = container;
+ }
+
+ /**
+ * Activates or deactivates the bean
+ *
+ * @param active
+ * true
if the bean is active and initialisation should complete
+ */
+ public final void setActive(final boolean active)
+ {
+ this.isActive = active;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public final boolean isActive()
+ {
+ return this.isActive;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void doFilter(final ServletContext context, final ServletRequest sreq, final ServletResponse sresp, final FilterChain chain)
+ throws IOException, ServletException
+ {
+ final HttpServletRequest req = (HttpServletRequest) sreq;
+
+ final String requestURI = req.getRequestURI();
+ final String pathInfo = requestURI.substring((req.getContextPath() + req.getServletPath()).length());
+
+ LOGGER.trace("Processing request: {} SID: {}", requestURI, req.getSession(false) != null ? req.getSession().getId() : null);
+
+ final Match match = this.container.getRegistry().findWebScript(req.getMethod(), URLDecoder.decode(pathInfo));
+ if (match != null && match.getWebScript() != null)
+ {
+ final RequiredAuthentication reqAuth = match.getWebScript().getDescription().getRequiredAuthentication();
+ if (RequiredAuthentication.none == reqAuth)
+ {
+ LOGGER.debug("Found webscript with no authentication - set NO_AUTH_REQUIRED flag.");
+ req.setAttribute(NO_AUTH_REQUIRED, Boolean.TRUE);
+ }
+ else if (RequiredAuthentication.guest == reqAuth && Boolean.parseBoolean(sreq.getParameter(ARG_GUEST)))
+ {
+ LOGGER.debug("Found webscript with guest authentication and request with set guest parameter - set NO_AUTH_REQUIRED flag.");
+ req.setAttribute(NO_AUTH_REQUIRED, Boolean.TRUE);
+ }
+ }
+
+ chain.doFilter(sreq, sresp);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ // ugh - Commons Logging - why does base class not have a sensible default??
+ protected Log getLogger()
+ {
+ return LogFactory.getLog(this.getClass());
+ }
+}
diff --git a/repository/src/main/java/de/acosix/alfresco/keycloak/repo/roles/RoleServiceImpl.java b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/roles/RoleServiceImpl.java
index 36700b4..51b8c99 100644
--- a/repository/src/main/java/de/acosix/alfresco/keycloak/repo/roles/RoleServiceImpl.java
+++ b/repository/src/main/java/de/acosix/alfresco/keycloak/repo/roles/RoleServiceImpl.java
@@ -312,7 +312,7 @@ public class RoleServiceImpl implements InitializingBean, RoleService
}
else
{
- LOGGER.debug("No role mapper defined for resource {}", roleNameMapper);
+ LOGGER.debug("No role mapper defined for resource {}", resourceName);
roles = Collections.emptyList();
}
}
diff --git a/repository/src/main/webscripts/de/acosix/acosix-keycloak/roles.get.desc.xml b/repository/src/main/webscripts/de/acosix/keycloak/roles.get.desc.xml
similarity index 100%
rename from repository/src/main/webscripts/de/acosix/acosix-keycloak/roles.get.desc.xml
rename to repository/src/main/webscripts/de/acosix/keycloak/roles.get.desc.xml
diff --git a/repository/src/main/webscripts/de/acosix/acosix-keycloak/roles.get.json.ftl b/repository/src/main/webscripts/de/acosix/keycloak/roles.get.json.ftl
similarity index 100%
rename from repository/src/main/webscripts/de/acosix/acosix-keycloak/roles.get.json.ftl
rename to repository/src/main/webscripts/de/acosix/keycloak/roles.get.json.ftl
diff --git a/repository/src/test/docker/test-realm.json b/repository/src/test/docker/test-realm.json
index 3143e3f..4abc0ee 100644
--- a/repository/src/test/docker/test-realm.json
+++ b/repository/src/test/docker/test-realm.json
@@ -1,1405 +1,165 @@
{
"id": "test",
"realm": "test",
- "groups": [{
- "name": "Test A",
- "subGroups": [{
- "name": "Test AA"
- }, {
- "name": "Test AB"
- }]
- }, {
- "name": "Test B",
- "subGroups": [{
- "name": "Test BA"
- }]
- }],
- "users": [{
- "id": "service-account-alfresco",
- "serviceAccountClientId": "alfresco",
- "username": "service-account-alfresco",
- "enabled": true,
- "email": "service-account-alfresco@muster.com",
- "realmRoles": [
- "offline_access",
- "uma_authorization"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ],
- "realm-management": [
- "view-users",
- "view-clients"
- ]
- }
- }, {
- "id": "mmustermann",
- "username": "mmustermann",
- "enabled": true,
- "email": "max.mustermann@muster.com",
- "firstName": "Max",
- "lastName": "Mustermann",
- "credentials": [{
- "type": "password",
- "value": "mmustermann"
- }],
- "realmRoles": [
- "user"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ]
- },
- "groups": [
- "/Test A/Test AB",
- "/Test B/Test BA"
- ]
- }, {
- "id": "jdoe",
- "username": "jdoe",
- "enabled": true,
- "email": "john.doe@muster.com",
- "firstName": "John",
- "lastName": "Doe",
- "credentials": [{
- "type": "password",
- "value": "jdoe"
- }],
- "realmRoles": [
- "user"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ]
- }
- }, {
- "id": "ssuper",
- "username": "ssuper",
- "enabled": true,
- "email": "suzy.super@muster.com",
- "firstName": "Suzy",
- "lastName": "Super",
- "credentials": [{
- "type": "password",
- "value": "ssuper"
- }],
- "realmRoles": [
- "user"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ],
- "alfresco": [
- "admin"
- ]
- }
- }],
- "roles": {
- "client": {
- "alfresco": [{
- "id": "57944d14-7240-464b-925d-7778fa9b78e6",
- "name": "admin",
- "composite": false,
- "clientRole": true,
- "attributes": {}
- }]
- }
- },
- "clients": [{
- "clientId": "alfresco",
- "name": "Alfresco Repository",
- "rootUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco",
- "adminUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco/keycloak",
- "baseUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "6f70a28f-98cd-41ca-8f2f-368a8797d708",
- "redirectUris": [
- "http://localhost:${docker.tests.repositoryPort}/alfresco/*"
- ],
- "webOrigins": [
- "http://localhost:${docker.tests.repositoryPort}"
- ],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": true,
- "publicClient": false,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {
- "saml.assertion.signature": "false",
- "saml.force.post.binding": "false",
- "saml.multivalued.roles": "false",
- "saml.encrypt": "false",
- "saml.server.signature": "false",
- "saml.server.signature.keyinfo.ext": "false",
- "exclude.session.state.from.auth.response": "false",
- "saml_force_name_id_format": "false",
- "saml.client.signature": "false",
- "tls.client.certificate.bound.access.tokens": "false",
- "saml.authnstatement": "false",
- "display.on.consent.screen": "false",
- "saml.onetimeuse.condition": "false"
- },
- "authenticationFlowBindingOverrides": {
-
- },
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": -1,
- "protocolMappers": [{
- "name": "groups",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-group-membership-mapper",
- "consentRequired": false,
- "config": {
- "full.path": "true",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "groups",
- "userinfo.token.claim": "true"
- }
- }],
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ],
- "access": {
- "view": true,
- "configure": true,
- "manage": true
- }
- }],
- "notBefore": 0,
- "revokeRefreshToken": false,
- "refreshTokenMaxReuse": 0,
- "accessTokenLifespan": 300,
- "accessTokenLifespanForImplicitFlow": 900,
- "ssoSessionIdleTimeout": 1800,
- "ssoSessionMaxLifespan": 36000,
- "ssoSessionIdleTimeoutRememberMe": 0,
- "ssoSessionMaxLifespanRememberMe": 0,
- "offlineSessionIdleTimeout": 2592000,
- "offlineSessionMaxLifespanEnabled": false,
- "offlineSessionMaxLifespan": 5184000,
- "accessCodeLifespan": 60,
- "accessCodeLifespanUserAction": 300,
- "accessCodeLifespanLogin": 1800,
- "actionTokenGeneratedByAdminLifespan": 43200,
- "actionTokenGeneratedByUserLifespan": 300,
"enabled": true,
"sslRequired": "none",
"registrationAllowed": false,
- "registrationEmailAsUsername": false,
- "rememberMe": false,
"verifyEmail": false,
- "loginWithEmailAllowed": true,
- "duplicateEmailsAllowed": false,
- "resetPasswordAllowed": false,
- "editUsernameAllowed": false,
- "bruteForceProtected": false,
- "permanentLockout": false,
- "maxFailureWaitSeconds": 900,
- "minimumQuickLoginWaitSeconds": 60,
- "waitIncrementSeconds": 60,
- "quickLoginCheckMilliSeconds": 1000,
- "maxDeltaTimeSeconds": 43200,
- "failureFactor": 30,
- "defaultRoles": [
- "offline_access",
- "uma_authorization"
+ "internationalizationEnabled": true,
+ "supportedLocales": [
+ "en"
],
- "requiredCredentials": [
- "password"
- ],
- "otpPolicyType": "totp",
- "otpPolicyAlgorithm": "HmacSHA1",
- "otpPolicyInitialCounter": 0,
- "otpPolicyDigits": 6,
- "otpPolicyLookAheadWindow": 1,
- "otpPolicyPeriod": 30,
- "otpSupportedApplications": [
- "FreeOTP",
- "Google Authenticator"
- ],
- "scopeMappings": [{
- "clientScope": "offline_access",
- "roles": [
- "offline_access"
- ]
- }],
- "clientScopes": [{
- "id": "0ee41513-079a-4156-9eab-5709b18be2a6",
- "name": "address",
- "description": "OpenID Connect built-in scope: address",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${addressScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "1218801d-c159-4ddd-901c-2fc5afa06170",
- "name": "address",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-address-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute.formatted": "formatted",
- "user.attribute.country": "country",
- "user.attribute.postal_code": "postal_code",
- "userinfo.token.claim": "true",
- "user.attribute.street": "street",
- "id.token.claim": "true",
- "user.attribute.region": "region",
- "access.token.claim": "true",
- "user.attribute.locality": "locality"
- }
- }]
- },
+ "defaultLocale": "en",
+ "clients": [
{
- "id": "bac1ffb3-92bf-481d-b6f8-8dec9bbe7291",
- "name": "email",
- "description": "OpenID Connect built-in scope: email",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${emailScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "4f28826f-46c6-4fe9-b499-611b66d9bc6f",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "34521446-1260-416f-bbab-b13143cdf163",
- "name": "email verified",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "emailVerified",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email_verified",
- "jsonType.label": "boolean"
- }
- }
- ]
- },
- {
- "id": "7a6e0dc7-5a3b-4c0e-9a6c-48c08d62b3e8",
- "name": "microprofile-jwt",
- "description": "Microprofile - JWT built-in scope",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "false"
- },
- "protocolMappers": [{
- "id": "a69c70ca-70c0-465b-8faf-fffd427f90d9",
- "name": "groups",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-realm-role-mapper",
- "consentRequired": false,
- "config": {
- "multivalued": "true",
- "userinfo.token.claim": "true",
- "user.attribute": "foo",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "groups",
- "jsonType.label": "String"
- }
- },
- {
- "id": "5fadd383-2a4a-4970-a79e-9e9bc917476e",
- "name": "upn",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "upn",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "3080e57a-c685-473d-977e-268f85e4d62d",
- "name": "offline_access",
- "description": "OpenID Connect built-in scope: offline_access",
- "protocol": "openid-connect",
- "attributes": {
- "consent.screen.text": "${offlineAccessScopeConsentText}",
- "display.on.consent.screen": "true"
- }
- },
- {
- "id": "052c824f-caac-492c-9334-d68a1fe757e3",
- "name": "phone",
- "description": "OpenID Connect built-in scope: phone",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${phoneScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "850fe82e-ea0b-4cda-a0bc-dcc9d355c5a8",
- "name": "phone number verified",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "phoneNumberVerified",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "phone_number_verified",
- "jsonType.label": "boolean"
- }
- },
- {
- "id": "63bf589d-e07e-4bae-b057-e7a7b8c72dc4",
- "name": "phone number",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "phoneNumber",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "phone_number",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "d9c5f7c3-d075-4400-bf27-970df51c4217",
- "name": "profile",
- "description": "OpenID Connect built-in scope: profile",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${profileScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "da5905e2-00ee-4ed0-ab7d-cdac7ead6206",
- "name": "zoneinfo",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "zoneinfo",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "zoneinfo",
- "jsonType.label": "String"
- }
- },
- {
- "id": "ae7cf419-6550-449c-9df1-0386bb0ee652",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "ac275bed-9da2-4221-8b8b-f7b499cc2c4b",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": false,
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true",
- "userinfo.token.claim": "true"
- }
- },
- {
- "id": "3b88f7c9-62a1-42a2-b575-52181043e89c",
- "name": "middle name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "middleName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "middle_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "90145df4-77c3-4c7a-8e15-59434c46bea1",
- "name": "gender",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "gender",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "gender",
- "jsonType.label": "String"
- }
- },
- {
- "id": "5fea5786-6563-49c3-bdc1-26b125d5c8f0",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "f802a038-2b1a-4642-8758-2923a5d67d76",
- "name": "nickname",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "nickname",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "nickname",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7d050eba-1d77-480c-a12c-674d9201d790",
- "name": "picture",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "picture",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "picture",
- "jsonType.label": "String"
- }
- },
- {
- "id": "6b54ca21-d615-4ef3-a703-0c0f20d9f393",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "cd3664d6-1888-464f-b144-3d1d6f332956",
- "name": "profile",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "profile",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "profile",
- "jsonType.label": "String"
- }
- },
- {
- "id": "aafa8ba3-d0cd-4dd0-9238-73506a15b6b3",
- "name": "locale",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "locale",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "locale",
- "jsonType.label": "String"
- }
- },
- {
- "id": "52d6c5f9-d1cf-4dbd-a8f3-9ce438ee3868",
- "name": "birthdate",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "birthdate",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "birthdate",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7dba042a-bb94-4307-a547-a02a0ab2239e",
- "name": "website",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "website",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "website",
- "jsonType.label": "String"
- }
- },
- {
- "id": "a6fb8c23-cfb4-4a5f-afcf-1bd360959c6b",
- "name": "updated at",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "updatedAt",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "updated_at",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "3ddbd9c1-92f1-4717-870e-4492df1d463a",
- "name": "role_list",
- "description": "SAML role list",
- "protocol": "saml",
- "attributes": {
- "consent.screen.text": "${samlRoleListScopeConsentText}",
- "display.on.consent.screen": "true"
- },
- "protocolMappers": [{
- "id": "51899037-a3df-4924-bd73-81f07cfb3aa9",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- }]
- },
- {
- "id": "4c15f94e-f490-4541-8c14-7b4734d6999b",
- "name": "roles",
- "description": "OpenID Connect scope for add user roles to the access token",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "false",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${rolesScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "1908b63f-1be6-4f87-a947-30ee66721d05",
- "name": "audience resolve",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-audience-resolve-mapper",
- "consentRequired": false,
- "config": {
-
- }
- },
- {
- "id": "b830b103-f7af-4d78-8c44-53c6879544d6",
- "name": "client roles",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-client-role-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute": "foo",
- "access.token.claim": "true",
- "claim.name": "resource_access.${client_id}.roles",
- "jsonType.label": "String",
- "multivalued": "true"
- }
- },
- {
- "id": "c3e6e3d7-e462-4e25-9a7c-99c5eee63194",
- "name": "realm roles",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-realm-role-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute": "foo",
- "access.token.claim": "true",
- "claim.name": "realm_access.roles",
- "jsonType.label": "String",
- "multivalued": "true"
- }
- }
- ]
- },
- {
- "id": "a6c18942-1bf9-4024-855e-65a5df06d810",
- "name": "web-origins",
- "description": "OpenID Connect scope for add allowed web origins to the access token",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "false",
- "display.on.consent.screen": "false",
- "consent.screen.text": ""
- },
- "protocolMappers": [{
- "id": "4652b835-1693-45ae-bad5-b61b534610de",
- "name": "allowed web origins",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-allowed-origins-mapper",
- "consentRequired": false,
- "config": {
-
- }
- }]
+ "id": "alfresco",
+ "clientId": "alfresco",
+ "name": "Alfresco Repository",
+ "baseUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco",
+ "adminUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco/keycloak",
+ "redirectUris": [
+ "http://localhost:${docker.tests.repositoryPort}/alfresco/*"
+ ],
+ "webOrigins": [
+ "http://localhost:${docker.tests.repositoryPort}/alfresco"
+ ],
+ "enabled": true,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "6f70a28f-98cd-41ca-8f2f-368a8797d708",
+ "directAccessGrantsEnabled": true,
+ "serviceAccountsEnabled": true,
+ "publicClient": false,
+ "protocol": "openid-connect"
}
],
- "defaultDefaultClientScopes": [
- "role_list",
- "roles",
- "web-origins",
- "email",
- "profile"
- ],
- "defaultOptionalClientScopes": [
- "phone",
- "address",
- "offline_access",
- "microprofile-jwt"
- ],
- "browserSecurityHeaders": {
- "contentSecurityPolicyReportOnly": "",
- "xContentTypeOptions": "nosniff",
- "xRobotsTag": "none",
- "xFrameOptions": "SAMEORIGIN",
- "xXSSProtection": "1; mode=block",
- "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
- "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+ "roles": {
+ "client": {
+ "alfresco": [
+ {
+ "name": "admin",
+ "clientRole": true
+ }
+ ]
+ }
},
- "smtpServer": {
-
- },
- "eventsEnabled": false,
- "eventsListeners": [
- "jboss-logging"
- ],
- "enabledEventTypes": [],
- "adminEventsEnabled": false,
- "adminEventsDetailsEnabled": false,
- "components": {
- "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [{
- "id": "43a864c4-c4fa-4057-bf87-2ca409cde736",
- "name": "Max Clients Limit",
- "providerId": "max-clients",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "max-clients": [
- "200"
- ]
- }
- },
- {
- "id": "6d4772af-f62e-40e9-8370-44aebf0d694d",
- "name": "Consent Required",
- "providerId": "consent-required",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
-
- }
- },
- {
- "id": "d474b02e-7d04-41c1-9c01-328221daa836",
- "name": "Allowed Client Scopes",
- "providerId": "allowed-client-templates",
- "subType": "authenticated",
- "subComponents": {
-
- },
- "config": {
- "allow-default-scopes": [
- "true"
- ]
- }
- },
- {
- "id": "2f6ce962-4ad2-479b-87b2-35ea971039b1",
- "name": "Allowed Protocol Mapper Types",
- "providerId": "allowed-protocol-mappers",
- "subType": "authenticated",
- "subComponents": {
-
- },
- "config": {
- "allowed-protocol-mapper-types": [
- "oidc-address-mapper",
- "oidc-sha256-pairwise-sub-mapper",
- "oidc-usermodel-property-mapper",
- "oidc-usermodel-attribute-mapper",
- "saml-user-property-mapper",
- "saml-user-attribute-mapper",
- "saml-role-list-mapper",
- "oidc-full-name-mapper"
- ]
- }
- },
- {
- "id": "3f7ae6b8-63c8-4ddf-82d8-afebf153a41a",
- "name": "Full Scope Disabled",
- "providerId": "scope",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
-
- }
- },
- {
- "id": "49326837-fe7d-47d6-85e7-5dd4028f0cd3",
- "name": "Allowed Protocol Mapper Types",
- "providerId": "allowed-protocol-mappers",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "allowed-protocol-mapper-types": [
- "oidc-usermodel-property-mapper",
- "saml-role-list-mapper",
- "oidc-sha256-pairwise-sub-mapper",
- "oidc-full-name-mapper",
- "saml-user-property-mapper",
- "oidc-usermodel-attribute-mapper",
- "oidc-address-mapper",
- "saml-user-attribute-mapper"
- ]
- }
- },
- {
- "id": "c76f5e11-0576-4512-abf4-2d0b7cd5f355",
- "name": "Trusted Hosts",
- "providerId": "trusted-hosts",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "host-sending-registration-request-must-match": [
- "true"
- ],
- "client-uris-must-match": [
- "true"
- ]
- }
- },
- {
- "id": "144efd74-bbbd-4176-8760-0e0819a61e5c",
- "name": "Allowed Client Scopes",
- "providerId": "allowed-client-templates",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "allow-default-scopes": [
- "true"
- ]
- }
- }
- ],
- "org.keycloak.keys.KeyProvider": [{
- "id": "005993b6-dcb3-4ebf-b19c-7287c740bb79",
- "name": "rsa-generated",
- "providerId": "rsa-generated",
- "subComponents": {
-
- },
- "config": {
- "priority": [
- "100"
- ]
- }
- },
- {
- "id": "865ea0f7-9411-4985-8516-a3a7112204f4",
- "name": "aes-generated",
- "providerId": "aes-generated",
- "subComponents": {
-
- },
- "config": {
- "priority": [
- "100"
- ]
- }
- },
- {
- "id": "7783eb59-57b1-491b-a570-934811ac95c3",
- "name": "hmac-generated",
- "providerId": "hmac-generated",
- "subComponents": {
-
- },
- "config": {
- "priority": [
- "100"
- ],
- "algorithm": [
- "HS256"
- ]
- }
- }
- ]
- },
- "internationalizationEnabled": false,
- "supportedLocales": [],
- "authenticationFlows": [{
- "id": "50eda798-0ed6-4fd1-9071-977ca22b032f",
- "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
+ "groups": [
+ {
+ "name": "Test A",
+ "subGroups": [
+ {
+ "name": "Test AA"
},
{
- "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
+ "name": "Test AB"
}
]
},
{
- "id": "49354897-5c61-4aca-8b08-0601202abf49",
- "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
- },
+ "name": "Test B",
+ "subGroups": [
{
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
+ "name": "Test BA"
}
]
- },
- {
- "id": "f23bad00-b78e-4262-a025-5b2ef1d09dc4",
- "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": "15d11f2c-9f51-4e41-8ca7-020b7b9e9335",
- "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
- },
- {
- "authenticator": "client-secret-jwt",
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-x509",
- "requirement": "ALTERNATIVE",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "6846e2ce-b014-4296-a111-6f68ca10c985",
- "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": "9425e1d1-4533-413d-83c5-38c9657a355f",
- "alias": "docker auth",
- "description": "Used by Docker clients to authenticate against the IDP",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [{
- "authenticator": "docker-http-basic-authenticator",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }]
- },
- {
- "id": "eb15d55b-a601-493c-9f49-069695624ada",
- "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": "4fa685ea-65dd-4019-b3a3-a5f95b36e9f4",
- "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": "8edbb281-f132-4625-bf15-ebc314dd0c5d",
- "alias": "http challenge",
- "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [{
- "authenticator": "no-cookie-redirect",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "basic-auth",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "basic-auth-otp",
- "requirement": "DISABLED",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-spnego",
- "requirement": "DISABLED",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "88374fbb-95fa-4bd5-940a-1289a9a051f6",
- "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": "088ede2e-2dce-466d-b25f-62cc07c12bee",
- "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": "065e575d-20fe-45e1-ab7d-d54ef056db8e",
- "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": "e1f9c5ba-5e45-4c51-a3cb-c10303b8c02e",
- "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": "1593e111-7e5e-4ee2-b33d-f459834e4e3b",
- "alias": "create unique user config",
- "config": {
- "require.password.update.after.registration": "false"
+ "users": [
+ {
+ "id": "service-account-alfresco",
+ "serviceAccountClientId": "alfresco",
+ "username": "service-account-alfresco",
+ "enabled": true,
+ "email": "service-account-alfresco@muster.com",
+ "realmRoles": [
+ "offline_access",
+ "uma_authorization"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ],
+ "realm-management": [
+ "view-users",
+ "view-clients"
+ ]
}
},
{
- "id": "ae5f6b14-fb84-4320-90a4-da8c80c379bf",
- "alias": "review profile config",
- "config": {
- "update.profile.on.first.login": "missing"
+ "id": "mmustermann",
+ "username": "mmustermann",
+ "enabled": true,
+ "email": "max.mustermann@muster.com",
+ "firstName": "Max",
+ "lastName": "Mustermann",
+ "credentials": [
+ {
+ "type": "password",
+ "value": "mmustermann"
+ }
+ ],
+ "realmRoles": [
+ "user"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ]
+ },
+ "groups": [
+ "/Test A/Test AB",
+ "/Test B/Test BA"
+ ]
+ },
+ {
+ "id": "jdoe",
+ "username": "jdoe",
+ "enabled": true,
+ "email": "john.doe@muster.com",
+ "firstName": "John",
+ "lastName": "Doe",
+ "credentials": [
+ {
+ "type": "password",
+ "value": "jdoe"
+ }
+ ],
+ "realmRoles": [
+ "user"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ]
+ }
+ },
+ {
+ "id": "ssuper",
+ "username": "ssuper",
+ "enabled": true,
+ "email": "suzy.super@muster.com",
+ "firstName": "Suzy",
+ "lastName": "Super",
+ "credentials": [
+ {
+ "type": "password",
+ "value": "ssuper"
+ }
+ ],
+ "realmRoles": [
+ "user"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ],
+ "alfresco": [
+ "admin"
+ ]
}
}
- ],
- "requiredActions": [{
- "alias": "CONFIGURE_TOTP",
- "name": "Configure OTP",
- "providerId": "CONFIGURE_TOTP",
- "enabled": true,
- "defaultAction": false,
- "priority": 10,
- "config": {
-
- }
- },
- {
- "alias": "terms_and_conditions",
- "name": "Terms and Conditions",
- "providerId": "terms_and_conditions",
- "enabled": false,
- "defaultAction": false,
- "priority": 20,
- "config": {
-
- }
- },
- {
- "alias": "UPDATE_PASSWORD",
- "name": "Update Password",
- "providerId": "UPDATE_PASSWORD",
- "enabled": true,
- "defaultAction": false,
- "priority": 30,
- "config": {
-
- }
- },
- {
- "alias": "UPDATE_PROFILE",
- "name": "Update Profile",
- "providerId": "UPDATE_PROFILE",
- "enabled": true,
- "defaultAction": false,
- "priority": 40,
- "config": {
-
- }
- },
- {
- "alias": "VERIFY_EMAIL",
- "name": "Verify Email",
- "providerId": "VERIFY_EMAIL",
- "enabled": true,
- "defaultAction": false,
- "priority": 50,
- "config": {
-
- }
- }
- ],
- "browserFlow": "browser",
- "registrationFlow": "registration",
- "directGrantFlow": "direct grant",
- "resetCredentialsFlow": "reset credentials",
- "clientAuthenticationFlow": "clients",
- "dockerAuthenticationFlow": "docker auth",
- "attributes": {
- "_browser_header.xXSSProtection": "1; mode=block",
- "_browser_header.xFrameOptions": "SAMEORIGIN",
- "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains",
- "permanentLockout": "false",
- "quickLoginCheckMilliSeconds": "1000",
- "_browser_header.xRobotsTag": "none",
- "maxFailureWaitSeconds": "900",
- "minimumQuickLoginWaitSeconds": "60",
- "failureFactor": "30",
- "actionTokenGeneratedByUserLifespan": "300",
- "maxDeltaTimeSeconds": "43200",
- "_browser_header.xContentTypeOptions": "nosniff",
- "offlineSessionMaxLifespan": "5184000",
- "actionTokenGeneratedByAdminLifespan": "43200",
- "_browser_header.contentSecurityPolicyReportOnly": "",
- "bruteForceProtected": "false",
- "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
- "waitIncrementSeconds": "60",
- "offlineSessionMaxLifespanEnabled": "false"
- },
- "keycloakVersion": "6.0.1",
- "userManagedAccessAllowed": false
+ ]
}
\ No newline at end of file
diff --git a/share-dependencies/pom.xml b/share-dependencies/pom.xml
index 55519a5..b5ce84b 100644
--- a/share-dependencies/pom.xml
+++ b/share-dependencies/pom.xml
@@ -26,19 +26,20 @@
de.acosix.alfresco.keycloak.share.deps
Acosix Alfresco Keycloak - Share Dependencies Module
- Aggregate (Uber-)JAR of all dependencies for the Acosix Alfresco Keycloak Share Module
+ Aggregate (Uber-)JAR of all dependencies for the Acosix Alfresco Keycloak Share Module (except BouncyCastle)
org.keycloak
keycloak-adapter-core
+
- org.bouncycastle
+ com.sun.activation
*
- com.fasterxml.jackson.core
+ org.bouncycastle
*
@@ -48,13 +49,19 @@
org.keycloak
keycloak-servlet-adapter-spi
+
+
+ com.sun.activation
+ *
+
org.bouncycastle
*
+
- com.fasterxml.jackson.core
- *
+ org.apache.httpcomponents
+ httpcomponents-client
@@ -63,12 +70,13 @@
org.keycloak
keycloak-servlet-filter-adapter
+
- org.bouncycastle
+ com.sun.activation
*
- com.fasterxml.jackson.core
+ org.bouncycastle
*
@@ -77,6 +85,12 @@
org.keycloak
keycloak-authz-client
+
+
+ org.bouncycastle
+ *
+
+
@@ -97,6 +111,10 @@
org.keycloak
de.acosix.alfresco.keycloak.share.deps.keycloak
+
+ com.fasterxml.jackson
+ de.acosix.alfresco.keycloak.share.deps.jackson
+
org.jboss.logging
de.acosix.alfresco.keycloak.share.deps.jboss.logging
diff --git a/share/pom.xml b/share/pom.xml
index 71f5d58..150b686 100644
--- a/share/pom.xml
+++ b/share/pom.xml
@@ -27,6 +27,10 @@
de.acosix.alfresco.keycloak.share
Acosix Alfresco Keycloak - Share Module
+
+ 8380
+
+
@@ -38,6 +42,12 @@
test
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ 1.60
+
+
@@ -55,23 +65,21 @@
- org.keycloak
- keycloak-adapter-core
+ ${project.groupId}
+ de.acosix.alfresco.keycloak.share.deps
+ ${project.version}
+
+
+ org.keycloak
+ *
+
+
-
+
+
- org.keycloak
- keycloak-servlet-adapter-spi
-
-
-
- org.keycloak
- keycloak-servlet-filter-adapter
-
-
-
- org.keycloak
- keycloak-authz-client
+ org.bouncycastle
+ bcpkix-jdk15on
@@ -109,6 +117,16 @@
installable
+
+ org.orderofthebee.support-tools
+ support-tools-repo
+
+
+
+ org.orderofthebee.support-tools
+ support-tools-share
+
+
junit
junit
@@ -163,7 +181,13 @@
-
+
+
+
+ ${project.build.directory}/docker/share-logs:/usr/local/tomcat/logs
+
+
+
diff --git a/share/src/main/assembly/amp.xml b/share/src/main/assembly/amp.xml
index a4a92a2..f099c97 100644
--- a/share/src/main/assembly/amp.xml
+++ b/share/src/main/assembly/amp.xml
@@ -45,10 +45,8 @@
lib
- org.keycloak:*
- org.jboss.logging:*
org.bouncycastle:*
- com.fasterxml.jackson.core:*
+ ${project.groupId}:${project.artifactId}.deps:*
diff --git a/share/src/main/config/default-config.xml b/share/src/main/config/default-config.xml
index d89601b..131691c 100644
--- a/share/src/main/config/default-config.xml
+++ b/share/src/main/config/default-config.xml
@@ -25,7 +25,7 @@
-
+
true
@@ -50,7 +50,7 @@
-
+
60000
diff --git a/share/src/main/config/log4j.properties b/share/src/main/config/log4j.properties
index 18249c2..a38a08d 100644
--- a/share/src/main/config/log4j.properties
+++ b/share/src/main/config/log4j.properties
@@ -1 +1,5 @@
-log4j.logger.${project.artifactId}=INFO
\ No newline at end of file
+log4j.logger.${project.artifactId}=INFO
+log4j.logger.${project.artifactId}.deps=ERROR
+log4j.logger.${project.artifactId}.deps.keycloak=ERROR
+log4j.logger.${project.artifactId}.deps.jackson=ERROR
+log4j.logger.${project.artifactId}.deps.jboss=ERROR
\ No newline at end of file
diff --git a/share/src/main/globalConfig/site-data/extensions/acosix-keycloak-extension.xml b/share/src/main/globalConfig/site-data/extensions/acosix-keycloak-extension.xml
index fd423ab..2b99acf 100644
--- a/share/src/main/globalConfig/site-data/extensions/acosix-keycloak-extension.xml
+++ b/share/src/main/globalConfig/site-data/extensions/acosix-keycloak-extension.xml
@@ -27,15 +27,15 @@
org.alfresco
de.acosix.keycloak.customisations
-
-
- org.alfresco.share.pages
- de.acosix.keycloak.customisations.share.header
-
- share-header
-
-
+
+ org.alfresco.share.pages
+ de.acosix.keycloak.customisations.share.header
+
+ share-header
+
+
+
diff --git a/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElement.java b/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElement.java
index ac258ea..ba3016a 100644
--- a/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElement.java
+++ b/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElement.java
@@ -31,13 +31,12 @@ import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.ParameterCheck;
-import org.keycloak.representations.adapters.config.AdapterConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.extensions.config.ConfigElement;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
+import de.acosix.alfresco.keycloak.share.deps.jackson.annotation.JsonProperty;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.representations.adapters.config.AdapterConfig;
import de.acosix.alfresco.utility.share.config.BaseCustomConfigElement;
import de.acosix.alfresco.utility.share.config.ConfigValueHolder;
@@ -137,6 +136,8 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
protected final ConfigValueHolder socketTimeout = new ConfigValueHolder<>();
+ protected final ConfigValueHolder directAuthHost = new ConfigValueHolder<>();
+
/**
* Creates a new instance of this class.
*/
@@ -179,6 +180,23 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
this.socketTimeout.setValue(socketTimeout);
}
+ /**
+ * @return the directAuthHost
+ */
+ public String getDirectAuthHost()
+ {
+ return this.directAuthHost.getValue();
+ }
+
+ /**
+ * @param directAuthHost
+ * the directAuthHost to set
+ */
+ public void setDirectAuthHost(final String directAuthHost)
+ {
+ this.directAuthHost.setValue(directAuthHost);
+ }
+
/**
* Checks if a specific field is supported by this config element.
*
@@ -386,6 +404,16 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
otherConfigElement.getSocketTimeout() != null ? otherConfigElement.getSocketTimeout() : this.getSocketTimeout());
}
+ if (otherConfigElement.directAuthHost.isUnset())
+ {
+ combined.directAuthHost.unset();
+ }
+ else
+ {
+ combined.setDirectAuthHost(
+ otherConfigElement.getDirectAuthHost() != null ? otherConfigElement.getDirectAuthHost() : this.getDirectAuthHost());
+ }
+
return combined;
}
@@ -401,16 +429,12 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
builder.append(this.configValueByField);
builder.append(",markedAsUnset=");
builder.append(this.markedAsUnset);
- if (this.connectionTimeout != null)
- {
- builder.append(",connectionTimeout=");
- builder.append(this.connectionTimeout);
- }
- if (this.connectionTimeout != null)
- {
- builder.append(",socketTimeout=");
- builder.append(this.socketTimeout);
- }
+ builder.append(",connectionTimeout=");
+ builder.append(this.connectionTimeout);
+ builder.append(",socketTimeout=");
+ builder.append(this.socketTimeout);
+ builder.append(",directAuthHost=");
+ builder.append(this.directAuthHost);
builder.append("]");
return builder.toString();
}
@@ -432,8 +456,9 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
result = prime * result + valueHash;
}
- result = prime * result + (this.connectionTimeout != null ? this.connectionTimeout.hashCode() : 0);
- result = prime * result + (this.socketTimeout != null ? this.socketTimeout.hashCode() : 0);
+ result = prime * result + this.connectionTimeout.hashCode();
+ result = prime * result + this.socketTimeout.hashCode();
+ result = prime * result + this.directAuthHost.hashCode();
return result;
}
diff --git a/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElementReader.java b/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElementReader.java
index bbc3f03..247693e 100644
--- a/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElementReader.java
+++ b/share/src/main/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigElementReader.java
@@ -129,6 +129,10 @@ public class KeycloakAdapterConfigElementReader implements ConfigElementReader
final String prospectiveSocketTimeout = subElement.getTextTrim();
configElement.setSocketTimeout(prospectiveSocketTimeout.isEmpty() ? null : Long.valueOf(prospectiveSocketTimeout));
break;
+ case "directAuthHost":
+ final String prospectiveDirectAuthHost = subElement.getTextTrim();
+ configElement.setDirectAuthHost(prospectiveDirectAuthHost.isEmpty() ? null : prospectiveDirectAuthHost);
+ break;
default:
LOGGER.warn("Encountered unsupported Keycloak Adapter config element {}", subElementName);
}
diff --git a/share/src/main/java/de/acosix/alfresco/keycloak/share/spring/KeycloakAuthenticationFilterActivation.java b/share/src/main/java/de/acosix/alfresco/keycloak/share/spring/KeycloakAuthenticationFilterActivation.java
index 9aa6fd3..31703a8 100644
--- a/share/src/main/java/de/acosix/alfresco/keycloak/share/spring/KeycloakAuthenticationFilterActivation.java
+++ b/share/src/main/java/de/acosix/alfresco/keycloak/share/spring/KeycloakAuthenticationFilterActivation.java
@@ -78,6 +78,8 @@ public class KeycloakAuthenticationFilterActivation implements BeanDefinitionReg
if (registry.containsBeanDefinition(keycloakFilterBeanName))
{
+ LOGGER.debug("Activating KeycloakAuthenticationFilter bean");
+
// re-register default filter under different name
final BeanDefinition defaultSsoAuthenticationFilter = registry.getBeanDefinition(DEFAULT_SSO_AUTHENTICATION_FILTER_NAME);
registry.removeBeanDefinition(DEFAULT_SSO_AUTHENTICATION_FILTER_NAME);
@@ -92,6 +94,8 @@ public class KeycloakAuthenticationFilterActivation implements BeanDefinitionReg
keycloakSsoAuthenticationFilter.getPropertyValues().add("defaultSsoFilter",
new RuntimeBeanReference(defaultSsoAuthenticationFilterReplacementName));
registry.registerBeanDefinition(DEFAULT_SSO_AUTHENTICATION_FILTER_NAME, keycloakSsoAuthenticationFilter);
+
+ LOGGER.debug("Activated KeycloakAuthenticationFilter bean");
}
else
{
diff --git a/share/src/main/java/de/acosix/alfresco/keycloak/share/web/DefaultSessionIdMapper.java b/share/src/main/java/de/acosix/alfresco/keycloak/share/web/DefaultSessionIdMapper.java
index 742ffdc..9391310 100644
--- a/share/src/main/java/de/acosix/alfresco/keycloak/share/web/DefaultSessionIdMapper.java
+++ b/share/src/main/java/de/acosix/alfresco/keycloak/share/web/DefaultSessionIdMapper.java
@@ -25,14 +25,14 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.keycloak.adapters.spi.InMemorySessionIdMapper;
-import org.keycloak.adapters.spi.SessionIdMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.extensions.config.ConfigService;
import de.acosix.alfresco.keycloak.share.config.KeycloakAuthenticationConfigElement;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.InMemorySessionIdMapper;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.SessionIdMapper;
/**
* This implementation of a {@link SessionIdMapper Keycloak session ID mapper} is based on the {@link InMemorySessionIdMapper in-memory
diff --git a/share/src/main/java/de/acosix/alfresco/keycloak/share/web/KeycloakAuthenticationFilter.java b/share/src/main/java/de/acosix/alfresco/keycloak/share/web/KeycloakAuthenticationFilter.java
index ef920c4..909df8c 100644
--- a/share/src/main/java/de/acosix/alfresco/keycloak/share/web/KeycloakAuthenticationFilter.java
+++ b/share/src/main/java/de/acosix/alfresco/keycloak/share/web/KeycloakAuthenticationFilter.java
@@ -16,6 +16,7 @@
package de.acosix.alfresco.keycloak.share.web;
import java.io.IOException;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -38,25 +39,12 @@ import javax.servlet.http.HttpSession;
import org.alfresco.util.PropertyCheck;
import org.alfresco.web.site.servlet.SSOAuthenticationFilter;
-import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.adapters.AdapterDeploymentContext;
-import org.keycloak.adapters.AuthenticatedActionsHandler;
-import org.keycloak.adapters.HttpClientBuilder;
-import org.keycloak.adapters.KeycloakDeployment;
-import org.keycloak.adapters.KeycloakDeploymentBuilder;
-import org.keycloak.adapters.OAuthRequestAuthenticator;
-import org.keycloak.adapters.OidcKeycloakAccount;
-import org.keycloak.adapters.PreAuthActionsHandler;
-import org.keycloak.adapters.servlet.FilterRequestAuthenticator;
-import org.keycloak.adapters.servlet.OIDCFilterSessionStore;
-import org.keycloak.adapters.servlet.OIDCServletHttpFacade;
-import org.keycloak.adapters.spi.AuthOutcome;
-import org.keycloak.adapters.spi.AuthenticationError;
-import org.keycloak.adapters.spi.KeycloakAccount;
-import org.keycloak.adapters.spi.SessionIdMapper;
-import org.keycloak.adapters.spi.UserSessionManagement;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.adapters.config.AdapterConfig;
+import org.apache.http.HttpHost;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.params.ConnRoutePNames;
+import org.apache.http.conn.params.ConnRouteParams;
+import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.params.HttpParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
@@ -83,6 +71,25 @@ import org.springframework.extensions.webscripts.servlet.DependencyInjectedFilte
import de.acosix.alfresco.keycloak.share.config.KeycloakAdapterConfigElement;
import de.acosix.alfresco.keycloak.share.config.KeycloakAuthenticationConfigElement;
import de.acosix.alfresco.keycloak.share.config.KeycloakConfigConstants;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.KeycloakSecurityContext;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.AdapterDeploymentContext;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.AuthenticatedActionsHandler;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.HttpClientBuilder;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.KeycloakDeployment;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.KeycloakDeploymentBuilder;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.OAuthRequestAuthenticator;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.OidcKeycloakAccount;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.PreAuthActionsHandler;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.servlet.FilterRequestAuthenticator;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.servlet.OIDCFilterSessionStore;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.servlet.OIDCServletHttpFacade;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.AuthOutcome;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.AuthenticationError;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.KeycloakAccount;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.SessionIdMapper;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.UserSessionManagement;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.representations.AccessToken;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.representations.adapters.config.AdapterConfig;
import de.acosix.alfresco.keycloak.share.remote.BearerTokenAwareSlingshotAlfrescoConnector;
/**
@@ -259,7 +266,10 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
{
httpClientBuilder = httpClientBuilder.socketTimeout(socketTimeout.longValue(), TimeUnit.MILLISECONDS);
}
- this.keycloakDeployment.setClient(httpClientBuilder.build(adapterConfiguration));
+
+ final HttpClient client = httpClientBuilder.build(adapterConfiguration);
+ this.configureForcedRouteIfNecessary(keycloakAdapterConfig, client);
+ this.keycloakDeployment.setClient(client);
}
this.deploymentContext = new AdapterDeploymentContext(this.keycloakDeployment);
@@ -516,7 +526,6 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
}
else
{
-
if (authOutcome == AuthOutcome.NOT_ATTEMPTED)
{
LOGGER.debug("No authentication took place - continueing with filter chain processing");
@@ -1129,4 +1138,29 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
});
}
}
+
+ @SuppressWarnings("deprecation")
+ protected void configureForcedRouteIfNecessary(final KeycloakAdapterConfigElement configElement, final HttpClient client)
+ {
+ final String directAuthHost = configElement.getDirectAuthHost();
+ if (directAuthHost != null && !directAuthHost.isEmpty())
+ {
+ final HttpHost host = HttpHost.create(directAuthHost);
+ final HttpParams params = client.getParams();
+ final InetAddress local = ConnRouteParams.getLocalAddress(params);
+ final HttpHost proxy = ConnRouteParams.getDefaultProxy(params);
+ final boolean secure = host.getSchemeName().equalsIgnoreCase("https");
+
+ HttpRoute route;
+ if (proxy == null)
+ {
+ route = new HttpRoute(host, local, secure);
+ }
+ else
+ {
+ route = new HttpRoute(host, local, proxy, secure);
+ }
+ params.setParameter(ConnRoutePNames.FORCED_ROUTE, route);
+ }
+ }
}
diff --git a/share/src/main/java/de/acosix/alfresco/keycloak/share/web/ResponseHeaderCookieCaptureServletHttpFacade.java b/share/src/main/java/de/acosix/alfresco/keycloak/share/web/ResponseHeaderCookieCaptureServletHttpFacade.java
index 87c7195..8c53404 100644
--- a/share/src/main/java/de/acosix/alfresco/keycloak/share/web/ResponseHeaderCookieCaptureServletHttpFacade.java
+++ b/share/src/main/java/de/acosix/alfresco/keycloak/share/web/ResponseHeaderCookieCaptureServletHttpFacade.java
@@ -26,8 +26,9 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.alfresco.util.Pair;
-import org.keycloak.adapters.servlet.ServletHttpFacade;
-import org.keycloak.adapters.spi.HttpFacade;
+
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.servlet.ServletHttpFacade;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.HttpFacade;
/**
* This {@link HttpFacade} wraps servlet requests and responses in such a way that any response headers / cookies being set by Keycloak
diff --git a/share/src/test/docker/alfresco/extension/alfresco-global.addition.properties b/share/src/test/docker/alfresco/extension/alfresco-global.addition.properties
index 12f06d8..795bafd 100644
--- a/share/src/test/docker/alfresco/extension/alfresco-global.addition.properties
+++ b/share/src/test/docker/alfresco/extension/alfresco-global.addition.properties
@@ -24,5 +24,8 @@ keycloak.adapter.resource=alfresco
keycloak.adapter.credentials.provider=secret
keycloak.adapter.credentials.secret=6f70a28f-98cd-41ca-8f2f-368a8797d708
+# localhost in auth-server-url won't work for direct access in a Docker deployment
+keycloak.authentication.directAuthHost=http://host.docker.internal:8380
+
keycloak.synchronization.userFilter.containedInGroup.property.groupPaths=/Test A
keycloak.synchronization.groupFilter.containedInGroup.property.groupPaths=/Test A
diff --git a/share/src/test/docker/alfresco/web-extension/dev-log4j.properties b/share/src/test/docker/alfresco/web-extension/dev-log4j.properties
new file mode 100644
index 0000000..9018760
--- /dev/null
+++ b/share/src/test/docker/alfresco/web-extension/dev-log4j.properties
@@ -0,0 +1,25 @@
+#
+# Copyright 2019 - 2020 Acosix GmbH
+#
+# 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.
+
+log4j.rootLogger=error, File
+
+log4j.appender.File=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.File.File=\${catalina.base}/logs/share.log
+log4j.appender.File.Append=true
+log4j.appender.File.DatePattern='.'yyyy-MM-dd
+log4j.appender.File.layout=org.apache.log4j.PatternLayout
+log4j.appender.File.layout.ConversionPattern=%d{yyyy-MM-dd} %d{ABSOLUTE} %-5p [%c] [%t] %m%n
+
+log4j.logger.${project.artifactId}=DEBUG
\ No newline at end of file
diff --git a/share/src/test/docker/alfresco/web-extension/share-config-custom.xml b/share/src/test/docker/alfresco/web-extension/share-config-custom.xml
index 1a76d9b..4570606 100644
--- a/share/src/test/docker/alfresco/web-extension/share-config-custom.xml
+++ b/share/src/test/docker/alfresco/web-extension/share-config-custom.xml
@@ -16,13 +16,76 @@
-->
-
+
+
+
+ alfrescoCookie
+ Alfresco Connector
+ Connects to an Alfresco instance using cookie-based authentication
+ de.acosix.alfresco.keycloak.share.remote.BearerTokenAwareSlingshotAlfrescoConnector
+
+
+
+ alfrescoHeader
+ Alfresco Connector
+ Connects to an Alfresco instance using header and cookie-based authentication
+ de.acosix.alfresco.keycloak.share.remote.BearerTokenAwareSlingshotAlfrescoConnector
+ SsoUserHeader
+
+
+
+ alfresco
+ Alfresco - user access
+ Access to Alfresco Repository WebScripts that require user authentication
+ alfrescoCookie
+ http://repository:8080/alfresco/wcs
+ user
+ true
+
+
+
+ alfresco-feed
+ Alfresco Feed
+ Alfresco Feed - supports basic HTTP authentication via the EndPointProxyServlet
+ alfrescoHeader
+ http://repository:8080/alfresco/wcs
+ true
+ user
+ true
+
+
+
+ alfresco-api
+ alfresco
+ Alfresco Public API - user access
+ Access to Alfresco Repository Public API that require user authentication.
+ This makes use of the authentication that is provided by parent 'alfresco' endpoint.
+
+ alfrescoHeader
+ http://repository:8080/alfresco/api
+ user
+ true
+
+
+
+
+
+
+ true
+ true
+ false
+
+ http://host.docker.internal:8380
+ http://${docker.tests.host.name}:${docker.tests.keycloakPort}/auth
+ test
+ alfresco-share
+ none
+ false
- secret
- test
+ secret
+ a5b3e8bc-39cc-4ddd-8c8f-1c34e7a35975
- true
diff --git a/share/src/test/docker/repository-it.xml b/share/src/test/docker/repository-it.xml
index 817cda1..1d203a3 100644
--- a/share/src/test/docker/repository-it.xml
+++ b/share/src/test/docker/repository-it.xml
@@ -59,10 +59,16 @@
WEB-INF/lib
- ${project.groupId}:de.acosix.alfresco.keycloak.repo.deps:*
+
+
+
+ com.cronutils:*
+ net.time4j:*
+ org.orderofthebee.support-tools:support-tools-repo:*
de.acosix.alfresco.utility:de.acosix.alfresco.utility.common:*
de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.repo.quartz1:*
de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.repo.quartz2:*
+ ${project.groupId}:de.acosix.alfresco.keycloak.repo.deps:*
de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.repo:jar:installable:*
${project.groupId}:de.acosix.alfresco.keycloak.repo:jar:installable:*
diff --git a/share/src/test/docker/share-it.xml b/share/src/test/docker/share-it.xml
index 29fa83a..32dd0f1 100644
--- a/share/src/test/docker/share-it.xml
+++ b/share/src/test/docker/share-it.xml
@@ -23,13 +23,6 @@
dir
false
-
-
- ${project.basedir}/src/test/docker/share-log4j.properties
- WEB-INF/classes
- log4j.properties
-
-
${project.build.directory}
@@ -74,12 +67,14 @@
WEB-INF/lib
${project.groupId}:de.acosix.alfresco.keycloak.share.deps:*
+ org.bouncycastle:*
compile
WEB-INF/lib
+ org.orderofthebee.support-tools:support-tools-share:*
de.acosix.alfresco.utility:de.acosix.alfresco.utility.common:*
de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.share:jar:installable:*
diff --git a/share/src/test/docker/share-logs/dummy.properties b/share/src/test/docker/share-logs/dummy.properties
new file mode 100644
index 0000000..5d13f33
--- /dev/null
+++ b/share/src/test/docker/share-logs/dummy.properties
@@ -0,0 +1 @@
+# only exists to ensure Maven creates path in project ./target
\ No newline at end of file
diff --git a/share/src/test/docker/test-realm.json b/share/src/test/docker/test-realm.json
index 6a68685..a1c3221 100644
--- a/share/src/test/docker/test-realm.json
+++ b/share/src/test/docker/test-realm.json
@@ -1,1404 +1,182 @@
{
"id": "test",
"realm": "test",
- "groups": [{
- "name": "Test A",
- "subGroups": [{
- "name": "Test AA"
- }, {
- "name": "Test AB"
- }]
- }, {
- "name": "Test B",
- "subGroups": [{
- "name": "Test BA"
- }]
- }],
- "users": [{
- "id": "service-account-alfresco",
- "serviceAccountClientId": "alfresco",
- "username": "service-account-alfresco",
- "enabled": true,
- "email": "service-account-alfresco@muster.com",
- "realmRoles": [
- "offline_access",
- "uma_authorization"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ],
- "realm-management": [
- "view-users"
- ]
- }
- }, {
- "id": "mmustermann",
- "username": "mmustermann",
- "enabled": true,
- "email": "max.mustermann@muster.com",
- "firstName": "Max",
- "lastName": "Mustermann",
- "credentials": [{
- "type": "password",
- "value": "mmustermann"
- }],
- "realmRoles": [
- "user"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ]
- },
- "groups": [
- "/Test A/Test AB",
- "/Test B/Test BA"
- ]
- }, {
- "id": "jdoe",
- "username": "jdoe",
- "enabled": true,
- "email": "john.doe@muster.com",
- "firstName": "John",
- "lastName": "Doe",
- "credentials": [{
- "type": "password",
- "value": "jdoe"
- }],
- "realmRoles": [
- "user"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ]
- }
- }, {
- "id": "ssuper",
- "username": "ssuper",
- "enabled": true,
- "email": "suzy.super@muster.com",
- "firstName": "Suzy",
- "lastName": "Super",
- "credentials": [{
- "type": "password",
- "value": "ssuper"
- }],
- "realmRoles": [
- "user"
- ],
- "clientRoles": {
- "account": [
- "view-profile",
- "manage-account"
- ],
- "alfresco": [
- "admin"
- ]
- }
- }],
- "roles": {
- "client": {
- "alfresco": [{
- "id": "57944d14-7240-464b-925d-7778fa9b78e6",
- "name": "admin",
- "composite": false,
- "clientRole": true,
- "attributes": {}
- }]
- }
- },
- "clients": [{
- "clientId": "alfresco",
- "name": "Alfresco Repository",
- "rootUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco",
- "adminUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco/keycloak",
- "baseUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco",
- "surrogateAuthRequired": false,
- "enabled": true,
- "clientAuthenticatorType": "client-secret",
- "secret": "6f70a28f-98cd-41ca-8f2f-368a8797d708",
- "redirectUris": [
- "http://localhost:${docker.tests.repositoryPort}/alfresco/*"
- ],
- "webOrigins": [
- "http://localhost:${docker.tests.repositoryPort}"
- ],
- "notBefore": 0,
- "bearerOnly": false,
- "consentRequired": false,
- "standardFlowEnabled": true,
- "implicitFlowEnabled": false,
- "directAccessGrantsEnabled": true,
- "serviceAccountsEnabled": true,
- "publicClient": false,
- "frontchannelLogout": false,
- "protocol": "openid-connect",
- "attributes": {
- "saml.assertion.signature": "false",
- "saml.force.post.binding": "false",
- "saml.multivalued.roles": "false",
- "saml.encrypt": "false",
- "saml.server.signature": "false",
- "saml.server.signature.keyinfo.ext": "false",
- "exclude.session.state.from.auth.response": "false",
- "saml_force_name_id_format": "false",
- "saml.client.signature": "false",
- "tls.client.certificate.bound.access.tokens": "false",
- "saml.authnstatement": "false",
- "display.on.consent.screen": "false",
- "saml.onetimeuse.condition": "false"
- },
- "authenticationFlowBindingOverrides": {
-
- },
- "fullScopeAllowed": true,
- "nodeReRegistrationTimeout": -1,
- "protocolMappers": [{
- "name": "groups",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-group-membership-mapper",
- "consentRequired": false,
- "config": {
- "full.path": "true",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "groups",
- "userinfo.token.claim": "true"
- }
- }],
- "defaultClientScopes": [
- "web-origins",
- "role_list",
- "roles",
- "profile",
- "email"
- ],
- "optionalClientScopes": [
- "address",
- "phone",
- "offline_access",
- "microprofile-jwt"
- ],
- "access": {
- "view": true,
- "configure": true,
- "manage": true
- }
- }],
- "notBefore": 0,
- "revokeRefreshToken": false,
- "refreshTokenMaxReuse": 0,
- "accessTokenLifespan": 300,
- "accessTokenLifespanForImplicitFlow": 900,
- "ssoSessionIdleTimeout": 1800,
- "ssoSessionMaxLifespan": 36000,
- "ssoSessionIdleTimeoutRememberMe": 0,
- "ssoSessionMaxLifespanRememberMe": 0,
- "offlineSessionIdleTimeout": 2592000,
- "offlineSessionMaxLifespanEnabled": false,
- "offlineSessionMaxLifespan": 5184000,
- "accessCodeLifespan": 60,
- "accessCodeLifespanUserAction": 300,
- "accessCodeLifespanLogin": 1800,
- "actionTokenGeneratedByAdminLifespan": 43200,
- "actionTokenGeneratedByUserLifespan": 300,
"enabled": true,
"sslRequired": "none",
"registrationAllowed": false,
- "registrationEmailAsUsername": false,
- "rememberMe": false,
"verifyEmail": false,
- "loginWithEmailAllowed": true,
- "duplicateEmailsAllowed": false,
- "resetPasswordAllowed": false,
- "editUsernameAllowed": false,
- "bruteForceProtected": false,
- "permanentLockout": false,
- "maxFailureWaitSeconds": 900,
- "minimumQuickLoginWaitSeconds": 60,
- "waitIncrementSeconds": 60,
- "quickLoginCheckMilliSeconds": 1000,
- "maxDeltaTimeSeconds": 43200,
- "failureFactor": 30,
- "defaultRoles": [
- "offline_access",
- "uma_authorization"
+ "internationalizationEnabled": true,
+ "supportedLocales": [
+ "en"
],
- "requiredCredentials": [
- "password"
- ],
- "otpPolicyType": "totp",
- "otpPolicyAlgorithm": "HmacSHA1",
- "otpPolicyInitialCounter": 0,
- "otpPolicyDigits": 6,
- "otpPolicyLookAheadWindow": 1,
- "otpPolicyPeriod": 30,
- "otpSupportedApplications": [
- "FreeOTP",
- "Google Authenticator"
- ],
- "scopeMappings": [{
- "clientScope": "offline_access",
- "roles": [
- "offline_access"
- ]
- }],
- "clientScopes": [{
- "id": "0ee41513-079a-4156-9eab-5709b18be2a6",
- "name": "address",
- "description": "OpenID Connect built-in scope: address",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${addressScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "1218801d-c159-4ddd-901c-2fc5afa06170",
- "name": "address",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-address-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute.formatted": "formatted",
- "user.attribute.country": "country",
- "user.attribute.postal_code": "postal_code",
- "userinfo.token.claim": "true",
- "user.attribute.street": "street",
- "id.token.claim": "true",
- "user.attribute.region": "region",
- "access.token.claim": "true",
- "user.attribute.locality": "locality"
- }
- }]
- },
+ "defaultLocale": "en",
+ "clients": [
{
- "id": "bac1ffb3-92bf-481d-b6f8-8dec9bbe7291",
- "name": "email",
- "description": "OpenID Connect built-in scope: email",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${emailScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "4f28826f-46c6-4fe9-b499-611b66d9bc6f",
- "name": "email",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "email",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email",
- "jsonType.label": "String"
- }
- },
- {
- "id": "34521446-1260-416f-bbab-b13143cdf163",
- "name": "email verified",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "emailVerified",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "email_verified",
- "jsonType.label": "boolean"
- }
- }
- ]
- },
- {
- "id": "7a6e0dc7-5a3b-4c0e-9a6c-48c08d62b3e8",
- "name": "microprofile-jwt",
- "description": "Microprofile - JWT built-in scope",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "false"
- },
- "protocolMappers": [{
- "id": "a69c70ca-70c0-465b-8faf-fffd427f90d9",
- "name": "groups",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-realm-role-mapper",
- "consentRequired": false,
- "config": {
- "multivalued": "true",
- "userinfo.token.claim": "true",
- "user.attribute": "foo",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "groups",
- "jsonType.label": "String"
- }
- },
- {
- "id": "5fadd383-2a4a-4970-a79e-9e9bc917476e",
- "name": "upn",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "upn",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "3080e57a-c685-473d-977e-268f85e4d62d",
- "name": "offline_access",
- "description": "OpenID Connect built-in scope: offline_access",
- "protocol": "openid-connect",
- "attributes": {
- "consent.screen.text": "${offlineAccessScopeConsentText}",
- "display.on.consent.screen": "true"
- }
- },
- {
- "id": "052c824f-caac-492c-9334-d68a1fe757e3",
- "name": "phone",
- "description": "OpenID Connect built-in scope: phone",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${phoneScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "850fe82e-ea0b-4cda-a0bc-dcc9d355c5a8",
- "name": "phone number verified",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "phoneNumberVerified",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "phone_number_verified",
- "jsonType.label": "boolean"
- }
- },
- {
- "id": "63bf589d-e07e-4bae-b057-e7a7b8c72dc4",
- "name": "phone number",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "phoneNumber",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "phone_number",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "d9c5f7c3-d075-4400-bf27-970df51c4217",
- "name": "profile",
- "description": "OpenID Connect built-in scope: profile",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "true",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${profileScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "da5905e2-00ee-4ed0-ab7d-cdac7ead6206",
- "name": "zoneinfo",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "zoneinfo",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "zoneinfo",
- "jsonType.label": "String"
- }
- },
- {
- "id": "ae7cf419-6550-449c-9df1-0386bb0ee652",
- "name": "given name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "firstName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "given_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "ac275bed-9da2-4221-8b8b-f7b499cc2c4b",
- "name": "full name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-full-name-mapper",
- "consentRequired": false,
- "config": {
- "id.token.claim": "true",
- "access.token.claim": "true",
- "userinfo.token.claim": "true"
- }
- },
- {
- "id": "3b88f7c9-62a1-42a2-b575-52181043e89c",
- "name": "middle name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "middleName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "middle_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "90145df4-77c3-4c7a-8e15-59434c46bea1",
- "name": "gender",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "gender",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "gender",
- "jsonType.label": "String"
- }
- },
- {
- "id": "5fea5786-6563-49c3-bdc1-26b125d5c8f0",
- "name": "family name",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "lastName",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "family_name",
- "jsonType.label": "String"
- }
- },
- {
- "id": "f802a038-2b1a-4642-8758-2923a5d67d76",
- "name": "nickname",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "nickname",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "nickname",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7d050eba-1d77-480c-a12c-674d9201d790",
- "name": "picture",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "picture",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "picture",
- "jsonType.label": "String"
- }
- },
- {
- "id": "6b54ca21-d615-4ef3-a703-0c0f20d9f393",
- "name": "username",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-property-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "username",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "preferred_username",
- "jsonType.label": "String"
- }
- },
- {
- "id": "cd3664d6-1888-464f-b144-3d1d6f332956",
- "name": "profile",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "profile",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "profile",
- "jsonType.label": "String"
- }
- },
- {
- "id": "aafa8ba3-d0cd-4dd0-9238-73506a15b6b3",
- "name": "locale",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "locale",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "locale",
- "jsonType.label": "String"
- }
- },
- {
- "id": "52d6c5f9-d1cf-4dbd-a8f3-9ce438ee3868",
- "name": "birthdate",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "birthdate",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "birthdate",
- "jsonType.label": "String"
- }
- },
- {
- "id": "7dba042a-bb94-4307-a547-a02a0ab2239e",
- "name": "website",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "website",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "website",
- "jsonType.label": "String"
- }
- },
- {
- "id": "a6fb8c23-cfb4-4a5f-afcf-1bd360959c6b",
- "name": "updated at",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-attribute-mapper",
- "consentRequired": false,
- "config": {
- "userinfo.token.claim": "true",
- "user.attribute": "updatedAt",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "claim.name": "updated_at",
- "jsonType.label": "String"
- }
- }
- ]
- },
- {
- "id": "3ddbd9c1-92f1-4717-870e-4492df1d463a",
- "name": "role_list",
- "description": "SAML role list",
- "protocol": "saml",
- "attributes": {
- "consent.screen.text": "${samlRoleListScopeConsentText}",
- "display.on.consent.screen": "true"
- },
- "protocolMappers": [{
- "id": "51899037-a3df-4924-bd73-81f07cfb3aa9",
- "name": "role list",
- "protocol": "saml",
- "protocolMapper": "saml-role-list-mapper",
- "consentRequired": false,
- "config": {
- "single": "false",
- "attribute.nameformat": "Basic",
- "attribute.name": "Role"
- }
- }]
- },
- {
- "id": "4c15f94e-f490-4541-8c14-7b4734d6999b",
- "name": "roles",
- "description": "OpenID Connect scope for add user roles to the access token",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "false",
- "display.on.consent.screen": "true",
- "consent.screen.text": "${rolesScopeConsentText}"
- },
- "protocolMappers": [{
- "id": "1908b63f-1be6-4f87-a947-30ee66721d05",
- "name": "audience resolve",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-audience-resolve-mapper",
- "consentRequired": false,
- "config": {
-
- }
- },
- {
- "id": "b830b103-f7af-4d78-8c44-53c6879544d6",
- "name": "client roles",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-client-role-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute": "foo",
- "access.token.claim": "true",
- "claim.name": "resource_access.${client_id}.roles",
- "jsonType.label": "String",
- "multivalued": "true"
- }
- },
- {
- "id": "c3e6e3d7-e462-4e25-9a7c-99c5eee63194",
- "name": "realm roles",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-usermodel-realm-role-mapper",
- "consentRequired": false,
- "config": {
- "user.attribute": "foo",
- "access.token.claim": "true",
- "claim.name": "realm_access.roles",
- "jsonType.label": "String",
- "multivalued": "true"
- }
- }
- ]
- },
- {
- "id": "a6c18942-1bf9-4024-855e-65a5df06d810",
- "name": "web-origins",
- "description": "OpenID Connect scope for add allowed web origins to the access token",
- "protocol": "openid-connect",
- "attributes": {
- "include.in.token.scope": "false",
- "display.on.consent.screen": "false",
- "consent.screen.text": ""
- },
- "protocolMappers": [{
- "id": "4652b835-1693-45ae-bad5-b61b534610de",
- "name": "allowed web origins",
- "protocol": "openid-connect",
- "protocolMapper": "oidc-allowed-origins-mapper",
- "consentRequired": false,
- "config": {
-
- }
- }]
+ "id": "alfresco",
+ "clientId": "alfresco",
+ "name": "Alfresco Repository",
+ "baseUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco",
+ "adminUrl": "http://localhost:${docker.tests.repositoryPort}/alfresco/keycloak",
+ "redirectUris": [
+ "http://localhost:${docker.tests.repositoryPort}/alfresco/*"
+ ],
+ "webOrigins": [
+ "http://localhost:${docker.tests.repositoryPort}/alfresco"
+ ],
+ "enabled": true,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "6f70a28f-98cd-41ca-8f2f-368a8797d708",
+ "directAccessGrantsEnabled": true,
+ "serviceAccountsEnabled": true,
+ "publicClient": false,
+ "protocol": "openid-connect"
+ }, {
+ "id": "alfresco-share",
+ "clientId": "alfresco-share",
+ "name": "Alfresco Share",
+ "baseUrl": "http://localhost:${docker.tests.sharePort}/share",
+ "adminUrl": "http://localhost:${docker.tests.sharePort}/share/keycloak",
+ "redirectUris": [
+ "http://localhost:${docker.tests.sharePort}/share/*"
+ ],
+ "webOrigins": [
+ "http://localhost:${docker.tests.sharePort}/share"
+ ],
+ "enabled": true,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "a5b3e8bc-39cc-4ddd-8c8f-1c34e7a35975",
+ "publicClient": false,
+ "protocol": "openid-connect"
}
],
- "defaultDefaultClientScopes": [
- "role_list",
- "roles",
- "web-origins",
- "email",
- "profile"
- ],
- "defaultOptionalClientScopes": [
- "phone",
- "address",
- "offline_access",
- "microprofile-jwt"
- ],
- "browserSecurityHeaders": {
- "contentSecurityPolicyReportOnly": "",
- "xContentTypeOptions": "nosniff",
- "xRobotsTag": "none",
- "xFrameOptions": "SAMEORIGIN",
- "xXSSProtection": "1; mode=block",
- "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
- "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+ "roles": {
+ "client": {
+ "alfresco": [
+ {
+ "name": "admin",
+ "clientRole": true
+ }
+ ]
+ }
},
- "smtpServer": {
-
- },
- "eventsEnabled": false,
- "eventsListeners": [
- "jboss-logging"
- ],
- "enabledEventTypes": [],
- "adminEventsEnabled": false,
- "adminEventsDetailsEnabled": false,
- "components": {
- "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [{
- "id": "43a864c4-c4fa-4057-bf87-2ca409cde736",
- "name": "Max Clients Limit",
- "providerId": "max-clients",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "max-clients": [
- "200"
- ]
- }
- },
- {
- "id": "6d4772af-f62e-40e9-8370-44aebf0d694d",
- "name": "Consent Required",
- "providerId": "consent-required",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
-
- }
- },
- {
- "id": "d474b02e-7d04-41c1-9c01-328221daa836",
- "name": "Allowed Client Scopes",
- "providerId": "allowed-client-templates",
- "subType": "authenticated",
- "subComponents": {
-
- },
- "config": {
- "allow-default-scopes": [
- "true"
- ]
- }
- },
- {
- "id": "2f6ce962-4ad2-479b-87b2-35ea971039b1",
- "name": "Allowed Protocol Mapper Types",
- "providerId": "allowed-protocol-mappers",
- "subType": "authenticated",
- "subComponents": {
-
- },
- "config": {
- "allowed-protocol-mapper-types": [
- "oidc-address-mapper",
- "oidc-sha256-pairwise-sub-mapper",
- "oidc-usermodel-property-mapper",
- "oidc-usermodel-attribute-mapper",
- "saml-user-property-mapper",
- "saml-user-attribute-mapper",
- "saml-role-list-mapper",
- "oidc-full-name-mapper"
- ]
- }
- },
- {
- "id": "3f7ae6b8-63c8-4ddf-82d8-afebf153a41a",
- "name": "Full Scope Disabled",
- "providerId": "scope",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
-
- }
- },
- {
- "id": "49326837-fe7d-47d6-85e7-5dd4028f0cd3",
- "name": "Allowed Protocol Mapper Types",
- "providerId": "allowed-protocol-mappers",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "allowed-protocol-mapper-types": [
- "oidc-usermodel-property-mapper",
- "saml-role-list-mapper",
- "oidc-sha256-pairwise-sub-mapper",
- "oidc-full-name-mapper",
- "saml-user-property-mapper",
- "oidc-usermodel-attribute-mapper",
- "oidc-address-mapper",
- "saml-user-attribute-mapper"
- ]
- }
- },
- {
- "id": "c76f5e11-0576-4512-abf4-2d0b7cd5f355",
- "name": "Trusted Hosts",
- "providerId": "trusted-hosts",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "host-sending-registration-request-must-match": [
- "true"
- ],
- "client-uris-must-match": [
- "true"
- ]
- }
- },
- {
- "id": "144efd74-bbbd-4176-8760-0e0819a61e5c",
- "name": "Allowed Client Scopes",
- "providerId": "allowed-client-templates",
- "subType": "anonymous",
- "subComponents": {
-
- },
- "config": {
- "allow-default-scopes": [
- "true"
- ]
- }
- }
- ],
- "org.keycloak.keys.KeyProvider": [{
- "id": "005993b6-dcb3-4ebf-b19c-7287c740bb79",
- "name": "rsa-generated",
- "providerId": "rsa-generated",
- "subComponents": {
-
- },
- "config": {
- "priority": [
- "100"
- ]
- }
- },
- {
- "id": "865ea0f7-9411-4985-8516-a3a7112204f4",
- "name": "aes-generated",
- "providerId": "aes-generated",
- "subComponents": {
-
- },
- "config": {
- "priority": [
- "100"
- ]
- }
- },
- {
- "id": "7783eb59-57b1-491b-a570-934811ac95c3",
- "name": "hmac-generated",
- "providerId": "hmac-generated",
- "subComponents": {
-
- },
- "config": {
- "priority": [
- "100"
- ],
- "algorithm": [
- "HS256"
- ]
- }
- }
- ]
- },
- "internationalizationEnabled": false,
- "supportedLocales": [],
- "authenticationFlows": [{
- "id": "50eda798-0ed6-4fd1-9071-977ca22b032f",
- "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
+ "groups": [
+ {
+ "name": "Test A",
+ "subGroups": [
+ {
+ "name": "Test AA"
},
{
- "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
+ "name": "Test AB"
}
]
},
{
- "id": "49354897-5c61-4aca-8b08-0601202abf49",
- "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
- },
+ "name": "Test B",
+ "subGroups": [
{
- "authenticator": "auth-otp-form",
- "requirement": "OPTIONAL",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
+ "name": "Test BA"
}
]
- },
- {
- "id": "f23bad00-b78e-4262-a025-5b2ef1d09dc4",
- "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": "15d11f2c-9f51-4e41-8ca7-020b7b9e9335",
- "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
- },
- {
- "authenticator": "client-secret-jwt",
- "requirement": "ALTERNATIVE",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "client-x509",
- "requirement": "ALTERNATIVE",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "6846e2ce-b014-4296-a111-6f68ca10c985",
- "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": "9425e1d1-4533-413d-83c5-38c9657a355f",
- "alias": "docker auth",
- "description": "Used by Docker clients to authenticate against the IDP",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [{
- "authenticator": "docker-http-basic-authenticator",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }]
- },
- {
- "id": "eb15d55b-a601-493c-9f49-069695624ada",
- "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": "4fa685ea-65dd-4019-b3a3-a5f95b36e9f4",
- "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": "8edbb281-f132-4625-bf15-ebc314dd0c5d",
- "alias": "http challenge",
- "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
- "providerId": "basic-flow",
- "topLevel": true,
- "builtIn": true,
- "authenticationExecutions": [{
- "authenticator": "no-cookie-redirect",
- "requirement": "REQUIRED",
- "priority": 10,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "basic-auth",
- "requirement": "REQUIRED",
- "priority": 20,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "basic-auth-otp",
- "requirement": "DISABLED",
- "priority": 30,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- },
- {
- "authenticator": "auth-spnego",
- "requirement": "DISABLED",
- "priority": 40,
- "userSetupAllowed": false,
- "autheticatorFlow": false
- }
- ]
- },
- {
- "id": "88374fbb-95fa-4bd5-940a-1289a9a051f6",
- "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": "088ede2e-2dce-466d-b25f-62cc07c12bee",
- "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": "065e575d-20fe-45e1-ab7d-d54ef056db8e",
- "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": "e1f9c5ba-5e45-4c51-a3cb-c10303b8c02e",
- "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": "1593e111-7e5e-4ee2-b33d-f459834e4e3b",
- "alias": "create unique user config",
- "config": {
- "require.password.update.after.registration": "false"
+ "users": [
+ {
+ "id": "service-account-alfresco",
+ "serviceAccountClientId": "alfresco",
+ "username": "service-account-alfresco",
+ "enabled": true,
+ "email": "service-account-alfresco@muster.com",
+ "realmRoles": [
+ "offline_access",
+ "uma_authorization"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ],
+ "realm-management": [
+ "view-users",
+ "view-clients"
+ ]
}
},
{
- "id": "ae5f6b14-fb84-4320-90a4-da8c80c379bf",
- "alias": "review profile config",
- "config": {
- "update.profile.on.first.login": "missing"
+ "id": "mmustermann",
+ "username": "mmustermann",
+ "enabled": true,
+ "email": "max.mustermann@muster.com",
+ "firstName": "Max",
+ "lastName": "Mustermann",
+ "credentials": [
+ {
+ "type": "password",
+ "value": "mmustermann"
+ }
+ ],
+ "realmRoles": [
+ "user"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ]
+ },
+ "groups": [
+ "/Test A/Test AB",
+ "/Test B/Test BA"
+ ]
+ },
+ {
+ "id": "jdoe",
+ "username": "jdoe",
+ "enabled": true,
+ "email": "john.doe@muster.com",
+ "firstName": "John",
+ "lastName": "Doe",
+ "credentials": [
+ {
+ "type": "password",
+ "value": "jdoe"
+ }
+ ],
+ "realmRoles": [
+ "user"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ]
+ }
+ },
+ {
+ "id": "ssuper",
+ "username": "ssuper",
+ "enabled": true,
+ "email": "suzy.super@muster.com",
+ "firstName": "Suzy",
+ "lastName": "Super",
+ "credentials": [
+ {
+ "type": "password",
+ "value": "ssuper"
+ }
+ ],
+ "realmRoles": [
+ "user"
+ ],
+ "clientRoles": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ],
+ "alfresco": [
+ "admin"
+ ]
}
}
- ],
- "requiredActions": [{
- "alias": "CONFIGURE_TOTP",
- "name": "Configure OTP",
- "providerId": "CONFIGURE_TOTP",
- "enabled": true,
- "defaultAction": false,
- "priority": 10,
- "config": {
-
- }
- },
- {
- "alias": "terms_and_conditions",
- "name": "Terms and Conditions",
- "providerId": "terms_and_conditions",
- "enabled": false,
- "defaultAction": false,
- "priority": 20,
- "config": {
-
- }
- },
- {
- "alias": "UPDATE_PASSWORD",
- "name": "Update Password",
- "providerId": "UPDATE_PASSWORD",
- "enabled": true,
- "defaultAction": false,
- "priority": 30,
- "config": {
-
- }
- },
- {
- "alias": "UPDATE_PROFILE",
- "name": "Update Profile",
- "providerId": "UPDATE_PROFILE",
- "enabled": true,
- "defaultAction": false,
- "priority": 40,
- "config": {
-
- }
- },
- {
- "alias": "VERIFY_EMAIL",
- "name": "Verify Email",
- "providerId": "VERIFY_EMAIL",
- "enabled": true,
- "defaultAction": false,
- "priority": 50,
- "config": {
-
- }
- }
- ],
- "browserFlow": "browser",
- "registrationFlow": "registration",
- "directGrantFlow": "direct grant",
- "resetCredentialsFlow": "reset credentials",
- "clientAuthenticationFlow": "clients",
- "dockerAuthenticationFlow": "docker auth",
- "attributes": {
- "_browser_header.xXSSProtection": "1; mode=block",
- "_browser_header.xFrameOptions": "SAMEORIGIN",
- "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains",
- "permanentLockout": "false",
- "quickLoginCheckMilliSeconds": "1000",
- "_browser_header.xRobotsTag": "none",
- "maxFailureWaitSeconds": "900",
- "minimumQuickLoginWaitSeconds": "60",
- "failureFactor": "30",
- "actionTokenGeneratedByUserLifespan": "300",
- "maxDeltaTimeSeconds": "43200",
- "_browser_header.xContentTypeOptions": "nosniff",
- "offlineSessionMaxLifespan": "5184000",
- "actionTokenGeneratedByAdminLifespan": "43200",
- "_browser_header.contentSecurityPolicyReportOnly": "",
- "bruteForceProtected": "false",
- "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
- "waitIncrementSeconds": "60",
- "offlineSessionMaxLifespanEnabled": "false"
- },
- "keycloakVersion": "6.0.1",
- "userManagedAccessAllowed": false
+ ]
}
\ No newline at end of file
diff --git a/share/src/test/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigTest.java b/share/src/test/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigTest.java
index 3659bc1..b934283 100644
--- a/share/src/test/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigTest.java
+++ b/share/src/test/java/de/acosix/alfresco/keycloak/share/config/KeycloakAdapterConfigTest.java
@@ -20,12 +20,14 @@ import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
-import org.keycloak.representations.adapters.config.AdapterConfig;
import org.springframework.extensions.config.Config;
+import org.springframework.extensions.config.ConfigElement;
import org.springframework.extensions.config.ConfigSource;
import org.springframework.extensions.config.source.UrlConfigSource;
import org.springframework.extensions.config.xml.XMLConfigService;
+import de.acosix.alfresco.keycloak.share.deps.keycloak.representations.adapters.config.AdapterConfig;
+
/**
* @author Axel Faust
*/
@@ -43,8 +45,9 @@ public class KeycloakAdapterConfigTest
final Config keycloakConfigSection = configService.getConfig(KeycloakConfigConstants.KEYCLOAK_CONFIG_SECTION_NAME);
- final KeycloakAuthenticationConfigElement keycloakAuthConfig = (KeycloakAuthenticationConfigElement) keycloakConfigSection
- .getConfigElement(KeycloakAuthenticationConfigElement.NAME);
+ final ConfigElement keycloakAuthConfigEl = keycloakConfigSection.getConfigElement(KeycloakAuthenticationConfigElement.NAME);
+ Assert.assertTrue(keycloakAuthConfigEl instanceof KeycloakAuthenticationConfigElement);
+ final KeycloakAuthenticationConfigElement keycloakAuthConfig = (KeycloakAuthenticationConfigElement) keycloakAuthConfigEl;
Assert.assertTrue(keycloakAuthConfig.getEnhanceLoginForm());
Assert.assertTrue(keycloakAuthConfig.getEnableSsoFilter());
@@ -89,8 +92,9 @@ public class KeycloakAdapterConfigTest
final Config keycloakConfigSection = configService.getConfig(KeycloakConfigConstants.KEYCLOAK_CONFIG_SECTION_NAME);
- final KeycloakAuthenticationConfigElement keycloakAuthConfig = (KeycloakAuthenticationConfigElement) keycloakConfigSection
- .getConfigElement(KeycloakAuthenticationConfigElement.NAME);
+ final ConfigElement keycloakAuthConfigEl = keycloakConfigSection.getConfigElement(KeycloakAuthenticationConfigElement.NAME);
+ Assert.assertTrue(keycloakAuthConfigEl instanceof KeycloakAuthenticationConfigElement);
+ final KeycloakAuthenticationConfigElement keycloakAuthConfig = (KeycloakAuthenticationConfigElement) keycloakAuthConfigEl;
Assert.assertFalse(keycloakAuthConfig.getEnhanceLoginForm());
Assert.assertFalse(keycloakAuthConfig.getEnableSsoFilter());
diff --git a/share/src/test/resources/default-config.xml b/share/src/test/resources/default-config.xml
index d89601b..af86ce2 100644
--- a/share/src/test/resources/default-config.xml
+++ b/share/src/test/resources/default-config.xml
@@ -50,7 +50,7 @@
-
+
60000