diff --git a/pom.xml b/pom.xml
index 403a32e..be5cec8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,12 +21,12 @@
de.acosix.alfresco.maven
de.acosix.alfresco.maven.project.parent-6.0.7
- 1.3.1
+ 1.3.3
de.acosix.alfresco.keycloak
de.acosix.alfresco.keycloak.parent
- 1.1.0-rc3
+ 1.1.0-rc4-SNAPSHOT
pom
Acosix Alfresco Keycloak - Parent
@@ -79,7 +79,7 @@
4.5.1
4.4.3
- 1.2.1
+ 1.2.3-SNAPSHOT
1.1.0.0
diff --git a/repository-dependencies/pom.xml b/repository-dependencies/pom.xml
index a3e5116..65b4a07 100644
--- a/repository-dependencies/pom.xml
+++ b/repository-dependencies/pom.xml
@@ -21,7 +21,7 @@
de.acosix.alfresco.keycloak
de.acosix.alfresco.keycloak.parent
- 1.1.0-rc3
+ 1.1.0-rc4-SNAPSHOT
de.acosix.alfresco.keycloak.repo.deps
diff --git a/repository/module.properties b/repository/module.properties
index 184584e..85caf06 100644
--- a/repository/module.properties
+++ b/repository/module.properties
@@ -5,4 +5,4 @@ module.version=${noSnapshotVersion}
module.repo.version.min=5
-module.depends.acosix-utility=1.1.0-*
\ No newline at end of file
+module.depends.acosix-utility=1.2.3-*
\ No newline at end of file
diff --git a/repository/pom.xml b/repository/pom.xml
index 810f2e3..f043952 100644
--- a/repository/pom.xml
+++ b/repository/pom.xml
@@ -21,7 +21,7 @@
de.acosix.alfresco.keycloak
de.acosix.alfresco.keycloak.parent
- 1.1.0-rc3
+ 1.1.0-rc4-SNAPSHOT
de.acosix.alfresco.keycloak.repo
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 290ec88..48c9066 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
@@ -693,7 +693,14 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
}
LOGGER.trace("Resetting session and state cookie before continueing with filter chain");
- req.getSession().invalidate();
+ try
+ {
+ req.getSession().invalidate();
+ }
+ catch (final IllegalStateException ignore)
+ {
+ // Keycloak authenticator may have already invalidated it - no way to check and avoid exception
+ }
this.resetStateCookies(context, req, res);
@@ -723,13 +730,13 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
boolean skip = false;
final String authHeader = req.getHeader(HEADER_AUTHORIZATION);
- final String noKeycloakLoginRedirectHeader = req.getHeader(this.noKeycloakHandlingHeaderName);
+ final String noKeycloakHandlingRedirectHeader = req.getHeader(this.noKeycloakHandlingHeaderName);
final String servletPath = req.getServletPath();
final String pathInfo = req.getPathInfo();
final String servletRequestUri = servletPath + (pathInfo != null ? pathInfo : "");
- final SessionUser sessionUser = this.getSessionUser(context, req, res, true);
+ SessionUser sessionUser = this.getSessionUser(context, req, res, true);
HttpSession session = req.getSession();
final boolean publicRestApi = API_SERVLET_PATH.equals(servletPath);
@@ -743,6 +750,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
LOGGER.debug("Session {} for Keycloak-authenticated user {} was invalidated by back-channel logout", session.getId(),
AlfrescoCompatibilityUtil.maskUsername(sessionUser.getUserName()));
this.invalidateSession(req);
+ sessionUser = null;
session = req.getSession(false);
}
@@ -908,7 +916,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
"Skipping processKeycloakAuthenticationAndActions as filter higher up in chain determined authentication as not required");
skip = true;
}
- else if (Boolean.parseBoolean(noKeycloakLoginRedirectHeader))
+ else if (Boolean.parseBoolean(noKeycloakHandlingRedirectHeader))
{
LOGGER.trace(
"Skipping processKeycloakAuthenticationAndActions as client provided custom 'no Keycloak handling' header {} with value that resolves to 'true'",
diff --git a/share-dependencies/pom.xml b/share-dependencies/pom.xml
index 135ff94..4b970a1 100644
--- a/share-dependencies/pom.xml
+++ b/share-dependencies/pom.xml
@@ -21,7 +21,7 @@
de.acosix.alfresco.keycloak
de.acosix.alfresco.keycloak.parent
- 1.1.0-rc3
+ 1.1.0-rc4-SNAPSHOT
de.acosix.alfresco.keycloak.share.deps
diff --git a/share/pom.xml b/share/pom.xml
index 6df536b..bf3a03f 100644
--- a/share/pom.xml
+++ b/share/pom.xml
@@ -21,7 +21,7 @@
de.acosix.alfresco.keycloak
de.acosix.alfresco.keycloak.parent
- 1.1.0-rc3
+ 1.1.0-rc4-SNAPSHOT
de.acosix.alfresco.keycloak.share
diff --git a/share/src/main/config/module-context.xml b/share/src/main/config/module-context.xml
index 7b4e970..4e81fd7 100644
--- a/share/src/main/config/module-context.xml
+++ b/share/src/main/config/module-context.xml
@@ -53,6 +53,7 @@
diff --git a/share/src/main/java/de/acosix/alfresco/keycloak/share/remote/AccessTokenAwareSlingshotAlfrescoConnector.java b/share/src/main/java/de/acosix/alfresco/keycloak/share/remote/AccessTokenAwareSlingshotAlfrescoConnector.java
index 590333d..6b41df7 100644
--- a/share/src/main/java/de/acosix/alfresco/keycloak/share/remote/AccessTokenAwareSlingshotAlfrescoConnector.java
+++ b/share/src/main/java/de/acosix/alfresco/keycloak/share/remote/AccessTokenAwareSlingshotAlfrescoConnector.java
@@ -32,6 +32,7 @@ import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.OidcKeycloakAcco
import de.acosix.alfresco.keycloak.share.deps.keycloak.adapters.spi.KeycloakAccount;
import de.acosix.alfresco.keycloak.share.util.RefreshableAccessTokenHolder;
import de.acosix.alfresco.keycloak.share.web.KeycloakAuthenticationFilter;
+import de.acosix.alfresco.utility.share.connector.MutableSlingshotRemoteClient;
/**
* @author Axel Faust
@@ -72,13 +73,26 @@ public class AccessTokenAwareSlingshotAlfrescoConnector extends SlingshotAlfresc
? session.getAttribute(KeycloakAuthenticationFilter.BACKEND_ACCESS_TOKEN_SESSION_KEY)
: null);
+ final MutableSlingshotRemoteClient mrc = remoteClient instanceof MutableSlingshotRemoteClient
+ ? (MutableSlingshotRemoteClient) remoteClient
+ : null;
+
if (endpointSpecificAccessToken != null)
{
if (endpointSpecificAccessToken.isActive())
{
LOGGER.debug("Using access token for backend found in session for request");
final String tokenString = endpointSpecificAccessToken.getToken();
- remoteClient.setRequestProperties(Collections.singletonMap("Authorization", "Bearer " + tokenString));
+ if (mrc != null)
+ {
+ mrc.addRemoveResponseHeader("WWW-Authenticate");
+ // must be request property to be a final override (other Alfresco components sets Authorization=null)
+ mrc.addRequestProperty("Authorization", "Bearer " + tokenString);
+ }
+ else
+ {
+ remoteClient.setRequestProperties(Collections.singletonMap("Authorization", "Bearer " + tokenString));
+ }
}
else
{
@@ -91,14 +105,32 @@ public class AccessTokenAwareSlingshotAlfrescoConnector extends SlingshotAlfresc
"Did not find access token for backend in session - using regularly authenticated Keycloak account access token for request instead");
final KeycloakSecurityContext keycloakSecurityContext = ((OidcKeycloakAccount) keycloakAccount).getKeycloakSecurityContext();
final String tokenString = keycloakSecurityContext.getTokenString();
- remoteClient.setRequestProperties(Collections.singletonMap("Authorization", "Bearer " + tokenString));
+ if (mrc != null)
+ {
+ mrc.addRemoveResponseHeader("WWW-Authenticate");
+ // must be request property to be a final override (other Alfresco components sets Authorization=null)
+ mrc.addRequestProperty("Authorization", "Bearer " + tokenString);
+ }
+ else
+ {
+ remoteClient.setRequestProperties(Collections.singletonMap("Authorization", "Bearer " + tokenString));
+ }
}
else if (accessToken != null)
{
LOGGER.debug(
"Did not find access token for backend in session - using Bearer access token provided in original authentication request for request instead");
final String tokenString = accessToken.getToken();
- remoteClient.setRequestProperties(Collections.singletonMap("Authorization", "Bearer " + tokenString));
+ if (mrc != null)
+ {
+ mrc.addRemoveResponseHeader("WWW-Authenticate");
+ // must be request property to be a final override (other Alfresco components sets Authorization=null)
+ mrc.addRequestProperty("Authorization", "Bearer " + tokenString);
+ }
+ else
+ {
+ remoteClient.setRequestProperties(Collections.singletonMap("Authorization", "Bearer " + tokenString));
+ }
}
else
{
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 472c71c..af68f5e 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
@@ -1025,7 +1025,14 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
authError != null ? authError : "");
LOGGER.debug("Resetting session and state cookie before continueing with filter chain");
- req.getSession().invalidate();
+ try
+ {
+ req.getSession().invalidate();
+ }
+ catch (final IllegalStateException ignore)
+ {
+ // Keycloak authenticator may have already invalidated it - no way to check and avoid exception
+ }
this.resetStateCookies(context, req, res);
@@ -1126,6 +1133,10 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
{
// variant with request AND response is only available in Spring 5+
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes((HttpServletRequest) request));
+ // a bit redundant since request attributes already holds the request, but hey, that's Alfresco
+ // ServletUtil uses an attribute in the request attributes object separate from the main request
+ // see ServletUtil.VIEW_REQUEST_ATTRIBUTE_NAME
+ ServletUtil.setRequest((HttpServletRequest) request);
}
try
@@ -1589,7 +1600,8 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
token = (RefreshableAccessTokenHolder) backendAccessTokenCandidate;
}
- // not really feasible to synchronise / lock concurrent refresh on token
+ // not really feasible to synchronise / lock concurrent refresh on token, especially given that we cannot lock across
+ // potentially multiple Share instances
// not a big problem - apart from wasted CPU cycles / latency - since each concurrently refreshed token is valid
// independently
if (token == null || !token.isActive()