mirror of
https://github.com/bmlong137/alfresco-keycloak.git
synced 2025-09-10 14:11:09 +00:00
Revise Share token exchange handling
- retry if refresh of exchanged token yields invalid token (wrong audience - known case of apparently incorrect Keycloak behaviour) - use custom header instead of redirect patch to have Repository tier not redirect to Keycloak login page on unauthenticated access from Share - activate audience verification which is inactive with Keycloak class defaults
This commit is contained in:
@@ -133,6 +133,7 @@
|
||||
<property name="handlePublicApi" value="${keycloak.authentication.sso.handlePublicApi}" />
|
||||
<property name="loginPageUrl" value="${keycloak.authentication.loginPageUrl}" />
|
||||
<property name="originalRequestUrlHeaderName" value="${keycloak.authentication.sso.originalRequestUrlHeaderName}" />
|
||||
<property name="noKeycloakHandlingHeaderName" value="x-${moduleId}-no-keycloak-handling" />
|
||||
<property name="bodyBufferLimit" value="${keycloak.authentication.bodyBufferLimit}" />
|
||||
<property name="sslRedirectPort" value="${keycloak.authentication.sslRedirectPort}" />
|
||||
<property name="keycloakDeployment" ref="keycloakDeployment" />
|
||||
|
@@ -19,7 +19,7 @@ keycloak.authentication.sslRedirectPort=8443
|
||||
keycloak.authentication.bodyBufferLimit=10485760
|
||||
|
||||
# override for a direct route to the auth server host
|
||||
# useful primarily for Dockerized deployments where container running Alfresco cannot resolve the auth server via the public DNS name
|
||||
# useful primarily for Docker-ized deployments where container running Alfresco cannot resolve the auth server via the public DNS name
|
||||
keycloak.authentication.directAuthHost=
|
||||
|
||||
keycloak.adapter.auth-server-url=http://localhost:8180/auth
|
||||
@@ -29,6 +29,8 @@ keycloak.adapter.ssl-required=none
|
||||
keycloak.adapter.public-client=false
|
||||
keycloak.adapter.credentials.provider=secret
|
||||
keycloak.adapter.credentials.secret=
|
||||
# for some reason, this is not a sane default in Keycloak Adapter config
|
||||
keycloak.adapter.verify-token-audience=true
|
||||
|
||||
# TODO default settings (identical to AdapterConfig defaults) to better align with default Alfresco subsystem property handling
|
||||
|
||||
|
@@ -116,6 +116,8 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
|
||||
|
||||
protected String originalRequestUrlHeaderName;
|
||||
|
||||
protected String noKeycloakHandlingHeaderName;
|
||||
|
||||
protected int bodyBufferLimit = DEFAULT_BODY_BUFFER_LIMIT;
|
||||
|
||||
// use 8443 as default SSL redirect based on Tomcat default server.xml configuration
|
||||
@@ -146,6 +148,8 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
|
||||
PropertyCheck.mandatory(this, "keycloakTicketTokenCache", this.keycloakTicketTokenCache);
|
||||
PropertyCheck.mandatory(this, "publicApiRuntimeContainer", this.publicApiRuntimeContainer);
|
||||
|
||||
PropertyCheck.mandatory(this, "noKeycloakHandlingHeaderName", this.noKeycloakHandlingHeaderName);
|
||||
|
||||
// parent class does not check, so we do
|
||||
PropertyCheck.mandatory(this, "authenticationService", this.authenticationService);
|
||||
PropertyCheck.mandatory(this, "authenticationComponent", this.authenticationComponent);
|
||||
@@ -222,6 +226,15 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
|
||||
this.originalRequestUrlHeaderName = originalRequestUrlHeaderName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param noKeycloakHandlingHeaderName
|
||||
* the noKeycloakHandlingHeaderName to set
|
||||
*/
|
||||
public void setNoKeycloakHandlingHeaderName(final String noKeycloakHandlingHeaderName)
|
||||
{
|
||||
this.noKeycloakHandlingHeaderName = noKeycloakHandlingHeaderName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bodyBufferLimit
|
||||
* the bodyBufferLimit to set
|
||||
@@ -710,6 +723,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
|
||||
boolean skip = false;
|
||||
|
||||
final String authHeader = req.getHeader(HEADER_AUTHORIZATION);
|
||||
final String noKeycloakLoginRedirectHeader = req.getHeader(this.noKeycloakHandlingHeaderName);
|
||||
|
||||
final String servletPath = req.getServletPath();
|
||||
final String pathInfo = req.getPathInfo();
|
||||
@@ -765,8 +779,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
|
||||
|
||||
// cannot rely on session.isNew() to determine if this is a fresh login
|
||||
// consider "fresh" login if issued within age limit (implicitly include any token refreshes performed client-side)
|
||||
final boolean isFreshLogin = accessToken.getIssuedAt()
|
||||
* 1000l > (System.currentTimeMillis() - FRESH_TOKEN_AGE_LIMIT_MS);
|
||||
final boolean isFreshLogin = accessToken.getIat() * 1000l > (System.currentTimeMillis() - FRESH_TOKEN_AGE_LIMIT_MS);
|
||||
this.keycloakAuthenticationComponent.handleUserTokens(accessToken, accessToken, isFreshLogin);
|
||||
|
||||
// sessionUser should be guaranteed here, but still check - we need it for the cache key
|
||||
@@ -857,9 +870,9 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
|
||||
"Skipping processKeycloakAuthenticationAndActions as request is aimed at a Public v1 ReST API which does not require authentication");
|
||||
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
|
||||
|
||||
// check no-auth flag (derived e.g. from checking if target web script requires authentication) as last resort to see if
|
||||
// we need to force authentication after invalidating session
|
||||
else if (Boolean.TRUE.equals(req.getAttribute(NO_AUTH_REQUIRED)))
|
||||
{
|
||||
LOGGER.trace(
|
||||
@@ -895,6 +908,13 @@ 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))
|
||||
{
|
||||
LOGGER.trace(
|
||||
"Skipping processKeycloakAuthenticationAndActions as client provided custom 'no Keycloak handling' header {} with value that resolves to 'true'",
|
||||
this.noKeycloakHandlingHeaderName);
|
||||
skip = true;
|
||||
}
|
||||
// TODO Check for login page URL (rarely configured since Repository by default has no login page since 5.0)
|
||||
|
||||
return skip;
|
||||
|
Reference in New Issue
Block a user