diff --git a/docker-test/src/main/resources/share/share-config-custom.xml b/docker-test/src/main/resources/share/share-config-custom.xml
index 7662bba..b37e2fb 100644
--- a/docker-test/src/main/resources/share/share-config-custom.xml
+++ b/docker-test/src/main/resources/share/share-config-custom.xml
@@ -33,6 +33,15 @@
de.acosix.alfresco.keycloak.share.remote.AccessTokenAwareAlfrescoAuthenticator
+
+ alfresco-noauth
+ Alfresco - unauthenticated access
+ Access to Alfresco Repository WebScripts that do not require authentication
+ alfresco
+ http://repository:8080/alfresco/s
+ none
+
+
alfresco
Alfresco - user access
@@ -71,7 +80,7 @@
true
true
- false
+ true
true
@@ -88,4 +97,61 @@
+
+
+
+ false
+ 1000
+ 7000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://repository:8080/alfresco
+
+ false
+
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
+ application/vnd.ms-powerpoint
+
+
+
+ false
+
+
\ No newline at end of file
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 caf6b73..ae0481a 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
@@ -179,6 +179,9 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
private static final String PAGE_TYPE_PARAMETER_NAME = "pt";
+ // used on some login page redirects - see PageView ALF_REDIRECT_URL constant
+ private static final String ALF_REDIRECT_URL = "alfRedirectUrl";
+
private static final String LOGIN_PATH_INFORMATION = "/dologin";
private static final String LOGOUT_PATH_INFORMATION = "/dologout";
@@ -527,13 +530,20 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
this.keycloakDeployment = KeycloakDeploymentBuilder.build(adapterConfiguration);
// we need to recreate the HttpClient to configure the forced route URL
- this.keycloakDeployment.setClient(new Callable() {
+ this.keycloakDeployment.setClient(new Callable()
+ {
+
private HttpClient client;
+
@Override
- public HttpClient call() throws Exception {
- if (this.client == null) {
- synchronized (this) {
- if (this.client == null) {
+ public HttpClient call() throws Exception
+ {
+ if (this.client == null)
+ {
+ synchronized (this)
+ {
+ if (this.client == null)
+ {
this.client = new HttpClientBuilder()
.routePlanner(KeycloakAuthenticationFilter.this.createForcedRoutePlanner(adapterConfiguration))
.build(adapterConfiguration);
@@ -845,11 +855,7 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
return cookie;
}).forEach(res::addCookie);
- final List redirects = captureFacade.getHeaders().get("Location");
- if (redirects != null && !redirects.isEmpty())
- {
- LOGIN_REDIRECT_URL.set(redirects.get(0));
- }
+ setRedirectFromCaptureFacade(req, captureFacade);
}
/**
@@ -881,6 +887,14 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
{
// no query parameters, so no code= and no error=
// this will cause login redirect challenge to be generated
+
+ // but use the alfRedirectUrl if present in request
+ final String alfRedirectUrl = req.getParameter(ALF_REDIRECT_URL);
+ if (alfRedirectUrl != null && !alfRedirectUrl.isBlank())
+ {
+ LOGGER.debug("Found {} query parameter with value {}", ALF_REDIRECT_URL, alfRedirectUrl);
+ return ALF_REDIRECT_URL + "=" + alfRedirectUrl;
+ }
return "";
}
@@ -915,10 +929,17 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
return cookie;
}).forEach(res::addCookie);
+ setRedirectFromCaptureFacade(req, captureFacade);
+ }
+
+ private static void setRedirectFromCaptureFacade(final HttpServletRequest req,
+ final ResponseHeaderCookieCaptureServletHttpFacade captureFacade)
+ {
final List redirects = captureFacade.getHeaders().get("Location");
if (redirects != null && !redirects.isEmpty())
{
- LOGIN_REDIRECT_URL.set(redirects.get(0));
+ final String redirectPath = redirects.get(0);
+ LOGIN_REDIRECT_URL.set(redirectPath);
}
}
@@ -961,9 +982,19 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
this.handleAlfrescoResourceAccessToken(session);
}
+ final String alfRedirectUrl = req.getParameter(ALF_REDIRECT_URL);
+
if (facade.isEnded())
{
LOGGER.debug("Authenticator already handled response");
+
+ if (alfRedirectUrl != null && !alfRedirectUrl.isBlank())
+ {
+ LOGGER.debug("Found {} query parameter - redirecting to {}", ALF_REDIRECT_URL, alfRedirectUrl);
+ // this may override any redirect set by the authenticator
+ res.sendRedirect(alfRedirectUrl);
+ }
+
return;
}
@@ -1022,9 +1053,19 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
session.setAttribute(UserFactory.SESSION_ATTRIBUTE_EXTERNAL_AUTH, Boolean.TRUE);
session.setAttribute(UserFactory.SESSION_ATTRIBUTE_KEY_USER_ID, userId);
+ final String alfRedirectUrl = req.getParameter(ALF_REDIRECT_URL);
+
if (facade.isEnded())
{
LOGGER.debug("Authenticator already handled response");
+
+ if (alfRedirectUrl != null && !alfRedirectUrl.isBlank())
+ {
+ LOGGER.debug("Found {} query parameter - redirecting to {}", ALF_REDIRECT_URL, alfRedirectUrl);
+ // this may override any redirect set by the authenticator
+ res.sendRedirect(alfRedirectUrl);
+ }
+
return;
}
@@ -1042,8 +1083,6 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
}
}
- this.completeRequestContext(req);
-
LOGGER.debug("Continueing with filter chain processing");
this.continueFilterChain(context, req, res, chain);
}
@@ -1773,11 +1812,9 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
final List headers = new LinkedList<>();
- ClientCredentialsProviderUtils.setClientCredentials(
- this.keycloakDeployment.getAdapterConfig(),
- this.keycloakDeployment.getClientAuthenticator(),
- new NameValueMapAdapter<>(headers, BasicHeader.class),
- new NameValueMapAdapter<>(formParams, BasicNameValuePair.class));
+ ClientCredentialsProviderUtils.setClientCredentials(this.keycloakDeployment.getAdapterConfig(),
+ this.keycloakDeployment.getClientAuthenticator(), new NameValueMapAdapter<>(headers, BasicHeader.class),
+ new NameValueMapAdapter<>(formParams, BasicNameValuePair.class));
for (final Header header : headers)
{
@@ -1900,41 +1937,54 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
params.setParameter(ConnRoutePNames.FORCED_ROUTE, route);
}
- protected HttpRoute createRoute(final ExtendedAdapterConfig adapterConfig, final HttpHost routeHost) throws UnknownHostException, MalformedURLException {
+ protected HttpRoute createRoute(final ExtendedAdapterConfig adapterConfig, final HttpHost routeHost)
+ throws UnknownHostException, MalformedURLException
+ {
final boolean secure = "https".equalsIgnoreCase(routeHost.getSchemeName());
- if (adapterConfig.getProxyUrl() != null) {
+ if (adapterConfig.getProxyUrl() != null)
+ {
// useful in parsing the URL for just what is needed for HttpHost
final URL proxyUrl = new URL(adapterConfig.getProxyUrl());
final HttpHost proxyHost = new HttpHost(proxyUrl.getHost(), proxyUrl.getPort(), proxyUrl.getProtocol());
return new HttpRoute(routeHost, InetAddress.getLocalHost(), proxyHost, secure);
- } else {
+ }
+ else
+ {
return new HttpRoute(routeHost, InetAddress.getLocalHost(), secure);
}
}
- protected HttpRoute createForcedRoute(final ExtendedAdapterConfig adapterConfig) throws UnknownHostException, MalformedURLException {
+ protected HttpRoute createForcedRoute(final ExtendedAdapterConfig adapterConfig) throws UnknownHostException, MalformedURLException
+ {
// useful in parsing the URL for just what is needed for HttpHost
final URL forcedRouteUrl = new URL(adapterConfig.getForcedRouteUrl());
final HttpHost forcedRouteHost = new HttpHost(forcedRouteUrl.getHost(), forcedRouteUrl.getPort(), forcedRouteUrl.getProtocol());
return this.createRoute(adapterConfig, forcedRouteHost);
}
- protected HttpRoutePlanner createForcedRoutePlanner(final ExtendedAdapterConfig adapterConfig) throws MalformedURLException {
+ protected HttpRoutePlanner createForcedRoutePlanner(final ExtendedAdapterConfig adapterConfig) throws MalformedURLException
+ {
final URL authServerUrl = new URL(adapterConfig.getAuthServerUrl());
final HttpHost authServerHost = new HttpHost(authServerUrl.getHost(), authServerUrl.getPort(), authServerUrl.getProtocol());
return (target, request, context) -> {
- try {
- if (authServerHost.equals(target)) {
+ try
+ {
+ if (authServerHost.equals(target))
+ {
LOGGER.trace("Rerouting to forced route");
final HttpRoute route = KeycloakAuthenticationFilter.this.createForcedRoute(adapterConfig);
LOGGER.trace("Rerouting to forced route: {}", route);
return route;
- } else {
+ }
+ else
+ {
return KeycloakAuthenticationFilter.this.createRoute(adapterConfig, target);
}
- } catch (final IOException ie) {
+ }
+ catch (final IOException ie)
+ {
throw new HttpException(ie.getMessage(), ie);
}
};
diff --git a/share/src/main/site-webscripts/de/acosix/keycloak/customisations/components/guest/login.get.js b/share/src/main/site-webscripts/de/acosix/keycloak/customisations/components/guest/login.get.js
index c76b637..fdc6cd6 100644
--- a/share/src/main/site-webscripts/de/acosix/keycloak/customisations/components/guest/login.get.js
+++ b/share/src/main/site-webscripts/de/acosix/keycloak/customisations/components/guest/login.get.js
@@ -44,7 +44,17 @@ function main()
parameterModel.value = decodeURIComponent(parameter.substring(parameter.indexOf('=') + 1));
if (parameterModel.value.indexOf('?') !== -1)
{
- parameterModel.value = parameterModel.value.substring(0, parameterModel.value.indexOf('?'));
+ if (parameterModel.value.indexOf('?alfRedirectUrl=') !== -1)
+ {
+ if (parameterModel.value.indexOf('&') !== -1)
+ {
+ parameterModel.value = parameterModel.value.substring(0, parameterModel.value.indexOf('&'));
+ }
+ }
+ else
+ {
+ parameterModel.value = parameterModel.value.substring(0, parameterModel.value.indexOf('?'));
+ }
}
}
else