mirror of
https://github.com/bmlong137/alfresco-keycloak.git
synced 2025-09-10 14:11:09 +00:00
Use default fields for timeout + proxy
This commit is contained in:
@@ -38,7 +38,6 @@
|
||||
<alfresco-resource-name>alfresco</alfresco-resource-name>
|
||||
</keycloak-auth-config>
|
||||
<keycloak-adapter-config>
|
||||
<!-- by default use the same client as alfresco (not really "clean") -->
|
||||
<auth-server-url>http://localhost:8180/auth</auth-server-url>
|
||||
<realm>alfresco</realm>
|
||||
<resource>alfresco-share</resource>
|
||||
@@ -51,8 +50,8 @@
|
||||
</credentials>
|
||||
<!-- for some reason, this is not a sane default in Keycloak Adapter config -->
|
||||
<verify-token-audience>true</verify-token-audience>
|
||||
<connectionTimeout>5000</connectionTimeout>
|
||||
<socketTimeout>5000</socketTimeout>
|
||||
<socket-timeout-millis>5000</socket-timeout-millis>
|
||||
<connection-timeout-millis>5000</connection-timeout-millis>
|
||||
</keycloak-adapter-config>
|
||||
</config>
|
||||
|
||||
|
@@ -134,12 +134,6 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
|
||||
|
||||
protected final Set<String> markedAsUnset = new HashSet<>();
|
||||
|
||||
protected final ConfigValueHolder<Long> connectionTimeout = new ConfigValueHolder<>();
|
||||
|
||||
protected final ConfigValueHolder<Long> socketTimeout = new ConfigValueHolder<>();
|
||||
|
||||
protected final ConfigValueHolder<String> directAuthHost = new ConfigValueHolder<>();
|
||||
|
||||
/**
|
||||
* Creates a new instance of this class.
|
||||
*/
|
||||
@@ -148,57 +142,6 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the connectionTimeout
|
||||
*/
|
||||
public Long getConnectionTimeout()
|
||||
{
|
||||
return this.connectionTimeout.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param connectionTimeout
|
||||
* the connectionTimeout to set
|
||||
*/
|
||||
public void setConnectionTimeout(final Long connectionTimeout)
|
||||
{
|
||||
this.connectionTimeout.setValue(connectionTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the socketTimeout
|
||||
*/
|
||||
public Long getSocketTimeout()
|
||||
{
|
||||
return this.socketTimeout.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param socketTimeout
|
||||
* the socketTimeout to set
|
||||
*/
|
||||
public void setSocketTimeout(final Long socketTimeout)
|
||||
{
|
||||
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.
|
||||
*
|
||||
@@ -390,36 +333,6 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
|
||||
}
|
||||
}
|
||||
|
||||
if (otherConfigElement.connectionTimeout.isUnset())
|
||||
{
|
||||
combined.connectionTimeout.unset();
|
||||
}
|
||||
else
|
||||
{
|
||||
combined.setConnectionTimeout(otherConfigElement.getConnectionTimeout() != null ? otherConfigElement.getConnectionTimeout()
|
||||
: this.getConnectionTimeout());
|
||||
}
|
||||
|
||||
if (otherConfigElement.socketTimeout.isUnset())
|
||||
{
|
||||
combined.socketTimeout.unset();
|
||||
}
|
||||
else
|
||||
{
|
||||
combined.setSocketTimeout(
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -435,12 +348,6 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
|
||||
builder.append(this.configValueByField);
|
||||
builder.append(",markedAsUnset=");
|
||||
builder.append(this.markedAsUnset);
|
||||
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();
|
||||
}
|
||||
@@ -462,10 +369,6 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
|
||||
result = prime * result + valueHash;
|
||||
}
|
||||
|
||||
result = prime * result + this.connectionTimeout.hashCode();
|
||||
result = prime * result + this.socketTimeout.hashCode();
|
||||
result = prime * result + this.directAuthHost.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -496,14 +399,6 @@ public class KeycloakAdapterConfigElement extends BaseCustomConfigElement
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!EqualsHelper.nullSafeEquals(this.connectionTimeout, other.connectionTimeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!EqualsHelper.nullSafeEquals(this.socketTimeout, other.socketTimeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -116,26 +116,7 @@ public class KeycloakAdapterConfigElementReader implements ConfigElementReader
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (subElementName)
|
||||
{
|
||||
// use -1 as dummy value for empty value to signify that empty value has explicitly been set (relevant for merge/combine
|
||||
// of config)
|
||||
case "connectionTimeout":
|
||||
final String prospectiveConnectionTimeout = subElement.getTextTrim();
|
||||
configElement.setConnectionTimeout(
|
||||
prospectiveConnectionTimeout.isEmpty() ? null : Long.valueOf(prospectiveConnectionTimeout));
|
||||
break;
|
||||
case "socketTimeout":
|
||||
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);
|
||||
}
|
||||
LOGGER.warn("Encountered unsupported Keycloak Adapter config element {}", subElementName);
|
||||
}
|
||||
}
|
||||
LOGGER.debug("Read configuration element {} from XML section", configElement);
|
||||
|
@@ -22,13 +22,11 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -50,17 +48,12 @@ import org.alfresco.util.EqualsHelper;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.alfresco.web.site.servlet.SSOAuthenticationFilter;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
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.message.BasicNameValuePair;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
@@ -68,7 +61,6 @@ import org.keycloak.TokenVerifier;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AuthenticatedActionsHandler;
|
||||
import org.keycloak.adapters.BearerTokenRequestAuthenticator;
|
||||
import org.keycloak.adapters.HttpClientBuilder;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.KeycloakDeploymentBuilder;
|
||||
import org.keycloak.adapters.OAuthRequestAuthenticator;
|
||||
@@ -512,35 +504,7 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
|
||||
protected void initFromAdapterConfig(final KeycloakAdapterConfigElement keycloakAdapterConfig)
|
||||
{
|
||||
final AdapterConfig adapterConfiguration = keycloakAdapterConfig.buildAdapterConfiguration();
|
||||
|
||||
// disable any CORS handling (if CORS is relevant, it should be handled by Share / Surf)
|
||||
adapterConfiguration.setCors(false);
|
||||
// BASIC authentication should never be used
|
||||
adapterConfiguration.setEnableBasicAuth(false);
|
||||
|
||||
this.keycloakDeployment = KeycloakDeploymentBuilder.build(adapterConfiguration);
|
||||
|
||||
// even in newer version than used by ACS 6.x does Keycloak lib not allow timeout configuration
|
||||
if (this.keycloakDeployment.getClient() != null)
|
||||
{
|
||||
final Long connectionTimeout = keycloakAdapterConfig.getConnectionTimeout();
|
||||
final Long socketTimeout = keycloakAdapterConfig.getSocketTimeout();
|
||||
|
||||
HttpClientBuilder httpClientBuilder = new HttpClientBuilder();
|
||||
if (connectionTimeout != null && connectionTimeout.longValue() >= 0)
|
||||
{
|
||||
httpClientBuilder = httpClientBuilder.establishConnectionTimeout(connectionTimeout.longValue(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
if (socketTimeout != null && socketTimeout.longValue() >= 0)
|
||||
{
|
||||
httpClientBuilder = httpClientBuilder.socketTimeout(socketTimeout.longValue(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
final HttpClient client = httpClientBuilder.build(adapterConfiguration);
|
||||
this.configureForcedRouteIfNecessary(keycloakAdapterConfig, client);
|
||||
this.keycloakDeployment.setClient(client);
|
||||
}
|
||||
|
||||
this.deploymentContext = new AdapterDeploymentContext(this.keycloakDeployment);
|
||||
}
|
||||
|
||||
@@ -1863,39 +1827,4 @@ public class KeycloakAuthenticationFilter implements DependencyInjectedFilter, I
|
||||
}
|
||||
return sslPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a forced route for the Keycloak-library backing HTTP client if configured. This may be necessary to deal with situations
|
||||
* where Share cannot use the public address of the authentication server (used in authentication redirects) to talk with the server
|
||||
* directly, due to network isolation / addressing restrictions (e.g. in Docker-ized deployments).
|
||||
*
|
||||
* @param configElement
|
||||
* the adapter configuration
|
||||
* @param client
|
||||
* the client to configure
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ 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.adapter.directAuthHost=http://keycloak:8080
|
||||
keycloak.adapter.proxy-url=http://keycloak:8080
|
||||
|
||||
keycloak.roles.requiredClientScopes=alfresco-role-service
|
||||
|
||||
|
@@ -75,7 +75,7 @@
|
||||
<perform-token-exchange>true</perform-token-exchange>
|
||||
</keycloak-auth-config>
|
||||
<keycloak-adapter-config>
|
||||
<directAuthHost>http://keycloak:8080</directAuthHost>
|
||||
<proxy-url>http://keycloak:8080</proxy-url>
|
||||
<auth-server-url>http://localhost:${docker.tests.keycloakPort}/auth</auth-server-url>
|
||||
<realm>test</realm>
|
||||
<resource>alfresco-share</resource>
|
||||
|
@@ -683,6 +683,7 @@
|
||||
"secret": "a5b3e8bc-39cc-4ddd-8c8f-1c34e7a35975",
|
||||
"publicClient": false,
|
||||
"protocol": "openid-connect",
|
||||
"alwaysDisplayInConsole": true,
|
||||
"fullScopeAllowed": false,
|
||||
"defaultClientScopes": [
|
||||
"roles",
|
||||
@@ -930,33 +931,36 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"defaultRole": {
|
||||
"name": "default-roles-test",
|
||||
"description": "${role_default-roles}",
|
||||
"composite": true,
|
||||
"composites": {
|
||||
"realm": [
|
||||
"offline_access",
|
||||
"uma_authorization",
|
||||
"user"
|
||||
],
|
||||
"client": {
|
||||
"account": [
|
||||
"view-profile",
|
||||
"manage-account"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"realm": [
|
||||
{
|
||||
"name": "uma_authorization",
|
||||
"description": "${role_uma_authorization}"
|
||||
},
|
||||
{
|
||||
"name": "default-roles-test",
|
||||
"description": "${role_default-roles}",
|
||||
"composite": true,
|
||||
"composites": {
|
||||
"realm": [
|
||||
"offline_access",
|
||||
"uma_authorization",
|
||||
"user"
|
||||
],
|
||||
"client": {
|
||||
"account": [
|
||||
"view-profile",
|
||||
"manage-account"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "offline_access",
|
||||
"description": "${role_offline-access}"
|
||||
},
|
||||
{
|
||||
"name": "user"
|
||||
}
|
||||
],
|
||||
"client": {
|
||||
|
@@ -40,7 +40,7 @@
|
||||
<alfresco-resource-name>alfresco</alfresco-resource-name>
|
||||
</keycloak-auth-config>
|
||||
<keycloak-adapter-config>
|
||||
<directAuthHost>http://keycloak:8080</directAuthHost>
|
||||
<proxy-url>http://keycloak:8080</proxy-url>
|
||||
<!-- by default use the same client as alfresco (not really "clean") -->
|
||||
<auth-server-url>http://localhost:8180/auth</auth-server-url>
|
||||
<realm>alfresco</realm>
|
||||
|
Reference in New Issue
Block a user