mirror of
https://github.com/bmlong137/alfresco-keycloak.git
synced 2025-09-10 14:11:09 +00:00
Fix Share working with recent Repository improvements
This commit is contained in:
@@ -33,6 +33,11 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
<exclusions>
|
||||
<!-- don't include activation standalone JAR - rely on JDK inclusion since Java 6 -->
|
||||
<exclusion>
|
||||
<groupId>com.sun.activation</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
@@ -48,6 +53,11 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-adapter-spi</artifactId>
|
||||
<exclusions>
|
||||
<!-- don't include activation standalone JAR - rely on JDK inclusion since Java 6 -->
|
||||
<exclusion>
|
||||
<groupId>com.sun.activation</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
@@ -56,6 +66,11 @@
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<!-- use default from Alfresco Repository -->
|
||||
<exclusion>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcomponents-client</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
@@ -63,6 +78,11 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-filter-adapter</artifactId>
|
||||
<exclusions>
|
||||
<!-- don't include activation standalone JAR - rely on JDK inclusion since Java 6 -->
|
||||
<exclusion>
|
||||
<groupId>com.sun.activation</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
|
@@ -1,2 +1,4 @@
|
||||
log4j.logger.${project.artifactId}=INFO
|
||||
log4j.logger.${project.artifactId}.deps=ERROR
|
||||
log4j.logger.${project.artifactId}.deps.keycloak=ERROR
|
||||
log4j.logger.${project.artifactId}.deps.jboss=ERROR
|
@@ -75,7 +75,7 @@
|
||||
<constructor-arg value="cache.${moduleId}.ticketTokenCache" />
|
||||
</bean>
|
||||
|
||||
<bean id="webscript.de.acosix.${moduleId}.roles.get" class="${project.artifactId}.web.scripts.RolesGet" parent="webscript">
|
||||
<bean id="webscript.de.acosix.keycloak.roles.get" class="${project.artifactId}.web.scripts.RolesGet" parent="webscript">
|
||||
<property name="roleService" ref="${moduleId}.RoleService" />
|
||||
</bean>
|
||||
|
||||
|
@@ -109,14 +109,21 @@
|
||||
<property name="personService" ref="PersonService" />
|
||||
</bean>
|
||||
|
||||
<bean id="webscriptAuthenticationFilter" class="org.alfresco.web.app.servlet.WebScriptSSOAuthenticationFilter">
|
||||
<bean id="webscriptAuthenticationFilter" class="${project.artifactId}.authentication.KeycloakWebScriptSSOAuthenticationFilter">
|
||||
<property name="active" value="${keycloak.authentication.enabled}" />
|
||||
<property name="container" ref="webscripts.container" />
|
||||
<!-- via inheritance, filter has way more fields, but only the above are actually needed -->
|
||||
</bean>
|
||||
|
||||
<!-- need to override this to align userAttributeName in session with other SSO filters -->
|
||||
<!-- for some reason, Alfresco is really inconsistent here between BaseAuthenticationFilter.AUTHENTICATION_USER and AuthenticationDriver.AUTHENTICATION_USER -->
|
||||
<bean id="cookieBasedAuthenticationFilter" class="${project.artifactId}.authentication.KeycloakWebScriptCookieAuthenticationFilter">
|
||||
<property name="authenticationService" ref="AuthenticationService" />
|
||||
<property name="authenticationComponent" ref="AuthenticationComponent" />
|
||||
<property name="personService" ref="personService" />
|
||||
<property name="personService" ref="PersonService" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="transactionService" ref="TransactionService" />
|
||||
<property name="container" ref="webscripts.container" />
|
||||
<property name="authenticationComponent" ref="AuthenticationComponent" />
|
||||
<property name="remoteUserMapper" ref="RemoteUserMapper" />
|
||||
</bean>
|
||||
|
||||
<bean id="globalAuthenticationFilter" class="${project.artifactId}.authentication.KeycloakAuthenticationFilter">
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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
|
||||
* <code>true</code> 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());
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -26,19 +26,20 @@
|
||||
|
||||
<artifactId>de.acosix.alfresco.keycloak.share.deps</artifactId>
|
||||
<name>Acosix Alfresco Keycloak - Share Dependencies Module</name>
|
||||
<description>Aggregate (Uber-)JAR of all dependencies for the Acosix Alfresco Keycloak Share Module</description>
|
||||
<description>Aggregate (Uber-)JAR of all dependencies for the Acosix Alfresco Keycloak Share Module (except BouncyCastle)</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
<exclusions>
|
||||
<!-- don't include activation standalone JAR - rely on JDK inclusion since Java 6 -->
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<groupId>com.sun.activation</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
@@ -48,13 +49,19 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-adapter-spi</artifactId>
|
||||
<exclusions>
|
||||
<!-- don't include activation standalone JAR - rely on JDK inclusion since Java 6 -->
|
||||
<exclusion>
|
||||
<groupId>com.sun.activation</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<!-- use default from Alfresco Share -->
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcomponents-client</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
@@ -63,12 +70,13 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-filter-adapter</artifactId>
|
||||
<exclusions>
|
||||
<!-- don't include activation standalone JAR - rely on JDK inclusion since Java 6 -->
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<groupId>com.sun.activation</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
@@ -77,6 +85,12 @@
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authz-client</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -97,6 +111,10 @@
|
||||
<pattern>org.keycloak</pattern>
|
||||
<shadedPattern>de.acosix.alfresco.keycloak.share.deps.keycloak</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.fasterxml.jackson</pattern>
|
||||
<shadedPattern>de.acosix.alfresco.keycloak.share.deps.jackson</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.jboss.logging</pattern>
|
||||
<shadedPattern>de.acosix.alfresco.keycloak.share.deps.jboss.logging</shadedPattern>
|
||||
|
@@ -27,6 +27,10 @@
|
||||
<artifactId>de.acosix.alfresco.keycloak.share</artifactId>
|
||||
<name>Acosix Alfresco Keycloak - Share Module</name>
|
||||
|
||||
<properties>
|
||||
<docker.tests.keycloakPort>8380</docker.tests.keycloakPort>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
@@ -38,6 +42,12 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.60</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@@ -55,23 +65,21 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>de.acosix.alfresco.keycloak.share.deps</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- BouncyCastle cannot be made part of an uber-JAR -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-adapter-spi</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-filter-adapter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authz-client</artifactId>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -109,6 +117,16 @@
|
||||
<classifier>installable</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.orderofthebee.support-tools</groupId>
|
||||
<artifactId>support-tools-repo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.orderofthebee.support-tools</groupId>
|
||||
<artifactId>support-tools-share</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
@@ -163,7 +181,13 @@
|
||||
</run>
|
||||
</image>
|
||||
<image>
|
||||
<!-- no change to Share image -->
|
||||
<run>
|
||||
<volumes>
|
||||
<bind>
|
||||
<volume>${project.build.directory}/docker/share-logs:/usr/local/tomcat/logs</volume>
|
||||
</bind>
|
||||
</volumes>
|
||||
</run>
|
||||
</image>
|
||||
<image>
|
||||
<!-- no change to Search image -->
|
||||
|
@@ -45,10 +45,8 @@
|
||||
<dependencySet>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<includes>
|
||||
<include>org.keycloak:*</include>
|
||||
<include>org.jboss.logging:*</include>
|
||||
<include>org.bouncycastle:*</include>
|
||||
<include>com.fasterxml.jackson.core:*</include>
|
||||
<include>${project.groupId}:${project.artifactId}.deps:*</include>
|
||||
</includes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
@@ -25,7 +25,7 @@
|
||||
</element-readers>
|
||||
</plug-ins>
|
||||
|
||||
<!-- sensible default configuration (similar to Repository identity-service-authentication.properties -->
|
||||
<!-- sensible default configuration -->
|
||||
<config evaluator="string-compare" condition="Keycloak">
|
||||
<keycloak-auth-config>
|
||||
<enhance-login-form>true</enhance-login-form>
|
||||
@@ -50,7 +50,7 @@
|
||||
</config>
|
||||
|
||||
<!-- add to the global configuration -->
|
||||
<config evaluator="string-compare">
|
||||
<config>
|
||||
<user>
|
||||
<!-- make sure groups of a user are kept up-to-date in at least 60 seconds intervals (lazily refreshed on next request) -->
|
||||
<cached-user-groups-timeout>60000</cached-user-groups-timeout>
|
||||
|
@@ -1 +1,5 @@
|
||||
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
|
@@ -27,7 +27,6 @@
|
||||
<targetPackageRoot>org.alfresco</targetPackageRoot>
|
||||
<sourcePackageRoot>de.acosix.keycloak.customisations</sourcePackageRoot>
|
||||
</customization>
|
||||
</customizations>
|
||||
|
||||
<customization>
|
||||
<targetPackageRoot>org.alfresco.share.pages</targetPackageRoot>
|
||||
@@ -36,6 +35,7 @@
|
||||
<webscript>share-header</webscript>
|
||||
</alwaysApply>
|
||||
</customization>
|
||||
</customizations>
|
||||
</module>
|
||||
</modules>
|
||||
</extension>
|
||||
|
@@ -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<Long> socketTimeout = new ConfigValueHolder<>();
|
||||
|
||||
protected final ConfigValueHolder<String> 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(",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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
@@ -16,13 +16,76 @@
|
||||
-->
|
||||
<alfresco-config>
|
||||
|
||||
<config evaluator="string-compare" condition="Test">
|
||||
<config evaluator="string-compare" condition="Remote">
|
||||
<remote>
|
||||
<connector>
|
||||
<id>alfrescoCookie</id>
|
||||
<name>Alfresco Connector</name>
|
||||
<description>Connects to an Alfresco instance using cookie-based authentication</description>
|
||||
<class>de.acosix.alfresco.keycloak.share.remote.BearerTokenAwareSlingshotAlfrescoConnector</class>
|
||||
</connector>
|
||||
|
||||
<connector>
|
||||
<id>alfrescoHeader</id>
|
||||
<name>Alfresco Connector</name>
|
||||
<description>Connects to an Alfresco instance using header and cookie-based authentication</description>
|
||||
<class>de.acosix.alfresco.keycloak.share.remote.BearerTokenAwareSlingshotAlfrescoConnector</class>
|
||||
<userHeader>SsoUserHeader</userHeader>
|
||||
</connector>
|
||||
|
||||
<endpoint>
|
||||
<id>alfresco</id>
|
||||
<name>Alfresco - user access</name>
|
||||
<description>Access to Alfresco Repository WebScripts that require user authentication</description>
|
||||
<connector-id>alfrescoCookie</connector-id>
|
||||
<endpoint-url>http://repository:8080/alfresco/wcs</endpoint-url>
|
||||
<identity>user</identity>
|
||||
<external-auth>true</external-auth>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<id>alfresco-feed</id>
|
||||
<name>Alfresco Feed</name>
|
||||
<description>Alfresco Feed - supports basic HTTP authentication via the EndPointProxyServlet</description>
|
||||
<connector-id>alfrescoHeader</connector-id>
|
||||
<endpoint-url>http://repository:8080/alfresco/wcs</endpoint-url>
|
||||
<basic-auth>true</basic-auth>
|
||||
<identity>user</identity>
|
||||
<external-auth>true</external-auth>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<id>alfresco-api</id>
|
||||
<parent-id>alfresco</parent-id>
|
||||
<name>Alfresco Public API - user access</name>
|
||||
<description>Access to Alfresco Repository Public API that require user authentication.
|
||||
This makes use of the authentication that is provided by parent 'alfresco' endpoint.
|
||||
</description>
|
||||
<connector-id>alfrescoHeader</connector-id>
|
||||
<endpoint-url>http://repository:8080/alfresco/api</endpoint-url>
|
||||
<identity>user</identity>
|
||||
<external-auth>true</external-auth>
|
||||
</endpoint>
|
||||
</remote>
|
||||
</config>
|
||||
|
||||
<config evaluator="string-compare" condition="Keycloak">
|
||||
<keycloak-auth-config>
|
||||
<enhance-login-form>true</enhance-login-form>
|
||||
<enable-sso-filter>true</enable-sso-filter>
|
||||
<force-keycloak-sso>false</force-keycloak-sso>
|
||||
</keycloak-auth-config>
|
||||
<keycloak-adapter-config>
|
||||
<directAuthHost>http://host.docker.internal:8380</directAuthHost>
|
||||
<auth-server-url>http://${docker.tests.host.name}:${docker.tests.keycloakPort}/auth</auth-server-url>
|
||||
<realm>test</realm>
|
||||
<resource>alfresco-share</resource>
|
||||
<ssl-required>none</ssl-required>
|
||||
<public-client>false</public-client>
|
||||
<credentials>
|
||||
<secret>secret</secret>
|
||||
<provider>test</provider>
|
||||
<provider>secret</provider>
|
||||
<secret>a5b3e8bc-39cc-4ddd-8c8f-1c34e7a35975</secret>
|
||||
</credentials>
|
||||
<allow-any-hostname>true</allow-any-hostname>
|
||||
</keycloak-adapter-config>
|
||||
</config>
|
||||
|
||||
|
@@ -59,10 +59,16 @@
|
||||
<dependencySet>
|
||||
<outputDirectory>WEB-INF/lib</outputDirectory>
|
||||
<includes>
|
||||
<include>${project.groupId}:de.acosix.alfresco.keycloak.repo.deps:*</include>
|
||||
<!-- TODO: Report bug against Maven PatternIncludesArtifactFilter#matchAgainst for incorrect return false-->
|
||||
<!-- when patterns with 5 tokens are listed in includes (like the installable JAR of Acosix Utility Core Repo), they may prevent evaluation of any additional patterns -->
|
||||
<!-- this cost me half a day to track down when the following three patterns were sorted last -->
|
||||
<include>com.cronutils:*</include>
|
||||
<include>net.time4j:*</include>
|
||||
<include>org.orderofthebee.support-tools:support-tools-repo:*</include>
|
||||
<include>de.acosix.alfresco.utility:de.acosix.alfresco.utility.common:*</include>
|
||||
<include>de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.repo.quartz1:*</include>
|
||||
<include>de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.repo.quartz2:*</include>
|
||||
<include>${project.groupId}:de.acosix.alfresco.keycloak.repo.deps:*</include>
|
||||
<include>de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.repo:jar:installable:*</include>
|
||||
<include>${project.groupId}:de.acosix.alfresco.keycloak.repo:jar:installable:*</include>
|
||||
</includes>
|
||||
|
@@ -23,13 +23,6 @@
|
||||
<format>dir</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<files>
|
||||
<file>
|
||||
<source>${project.basedir}/src/test/docker/share-log4j.properties</source>
|
||||
<outputDirectory>WEB-INF/classes</outputDirectory>
|
||||
<destName>log4j.properties</destName>
|
||||
</file>
|
||||
</files>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}</directory>
|
||||
@@ -74,12 +67,14 @@
|
||||
<outputDirectory>WEB-INF/lib</outputDirectory>
|
||||
<includes>
|
||||
<include>${project.groupId}:de.acosix.alfresco.keycloak.share.deps:*</include>
|
||||
<include>org.bouncycastle:*</include>
|
||||
</includes>
|
||||
<scope>compile</scope>
|
||||
</dependencySet>
|
||||
<dependencySet>
|
||||
<outputDirectory>WEB-INF/lib</outputDirectory>
|
||||
<includes>
|
||||
<include>org.orderofthebee.support-tools:support-tools-share:*</include>
|
||||
<include>de.acosix.alfresco.utility:de.acosix.alfresco.utility.common:*</include>
|
||||
<include>de.acosix.alfresco.utility:de.acosix.alfresco.utility.core.share:jar:installable:*</include>
|
||||
</includes>
|
||||
|
1
share/src/test/docker/share-logs/dummy.properties
Normal file
1
share/src/test/docker/share-logs/dummy.properties
Normal file
@@ -0,0 +1 @@
|
||||
# only exists to ensure Maven creates path in project ./target
|
File diff suppressed because it is too large
Load Diff
@@ -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());
|
||||
|
@@ -50,7 +50,7 @@
|
||||
</config>
|
||||
|
||||
<!-- add to the global configuration -->
|
||||
<config evaluator="string-compare">
|
||||
<config>
|
||||
<user>
|
||||
<!-- make sure groups of a user are kept up-to-date in at least 60 seconds intervals (lazily refreshed on next request) -->
|
||||
<cached-user-groups-timeout>60000</cached-user-groups-timeout>
|
||||
|
Reference in New Issue
Block a user