diff --git a/assembly-multiuser/dashboard/src/main/patches/src/app/index.module.ts.patch b/assembly-multiuser/dashboard/src/main/patches/src/app/index.module.ts.patch
index 54d85ddcff..6fbc4a5bc1 100644
--- a/assembly-multiuser/dashboard/src/main/patches/src/app/index.module.ts.patch
+++ b/assembly-multiuser/dashboard/src/main/patches/src/app/index.module.ts.patch
@@ -8,9 +8,9 @@
+
+function buildKeycloakConfig(keycloakSettings) {
+ return {
-+ url: keycloakSettings['che.keycloak.auth-server-url'],
++ url: keycloakSettings['che.keycloak.auth_server_url'],
+ realm: keycloakSettings['che.keycloak.realm'],
-+ clientId: keycloakSettings['che.keycloak.client-id']
++ clientId: keycloakSettings['che.keycloak.client_id']
+ };
+}
+
@@ -30,7 +30,7 @@
+ new Promise((resolve, reject) => {
+ const script = document.createElement('script');
+ script.async = true;
-+ script.src = keycloakSettings['che.keycloak.auth-server-url'] + '/js/keycloak.js';
++ script.src = keycloakSettings['che.keycloak.auth_server_url'] + '/js/keycloak.js';
+ script.addEventListener('load', resolve);
+ script.addEventListener('error', () => reject('Error loading script.'));
+ script.addEventListener('abort', () => reject('Script loading aborted.'));
diff --git a/dockerfiles/init/manifests/che.env b/dockerfiles/init/manifests/che.env
index 6dab4bcb13..8de51b911f 100644
--- a/dockerfiles/init/manifests/che.env
+++ b/dockerfiles/init/manifests/che.env
@@ -468,11 +468,11 @@ CHE_SINGLE_PORT=false
#
CHE_KEYCLOAK_OSO_ENDPOINT=NULL
-CHE_KEYCLOAK_GITHUB.ENDPOINT=NULL
-CHE_KEYCLOAK_AUTH-SERVER-URL=http://172.17.0.1:5050/auth
+CHE_KEYCLOAK_GITHUB_ENDPOINT=NULL
+CHE_KEYCLOAK_AUTH__SERVER__URL=http://172.17.0.1:5050/auth
CHE_KEYCLOAK_REALM=che
-CHE_KEYCLOAK_CLIENT-ID=che-public
+CHE_KEYCLOAK_CLIENT__ID=che-public
CHE_KEYCLOAK_PRIVATE_REALM=che
-CHE_KEYCLOAK_PRIVATE_CLIENT-ID=che
-CHE_KEYCLOAK_PRIVATE_CLIENT-SECRET=2c1b2621-d251-4701-82c4-a7dd447faa97
+CHE_KEYCLOAK_PRIVATE_CLIENT__ID=che
+CHE_KEYCLOAK_PRIVATE_CLIENT__SECRET=2c1b2621-d251-4701-82c4-a7dd447faa97
diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/AbstractKeycloakFilter.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/AbstractKeycloakFilter.java
new file mode 100644
index 0000000000..2677cf9020
--- /dev/null
+++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/AbstractKeycloakFilter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012-2017 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ */
+package org.eclipse.che.keycloak.server;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Base abstract class for the Keycloak-related servlet filters.
+ *
+ *
In particular it defines commnon use-cases when the authentication / multi-user logic should
+ * be skipped
+ */
+public abstract class AbstractKeycloakFilter implements Filter {
+
+ protected boolean shouldSkipAuthentication(HttpServletRequest request, String token) {
+ return request.getScheme().startsWith("ws") || (token != null && token.startsWith("machine"));
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {}
+
+ @Override
+ public void destroy() {}
+}
diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakAuthenticationFilter.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakAuthenticationFilter.java
index 21ce5a0ed4..ede6a2466c 100644
--- a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakAuthenticationFilter.java
+++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakAuthenticationFilter.java
@@ -29,9 +29,8 @@ import java.util.Base64;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
-import javax.servlet.Filter;
+import javax.inject.Singleton;
import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -42,7 +41,8 @@ import org.eclipse.che.keycloak.shared.KeycloakConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class KeycloakAuthenticationFilter implements Filter {
+@Singleton
+public class KeycloakAuthenticationFilter extends AbstractKeycloakFilter {
private static final Logger LOG = LoggerFactory.getLogger(KeycloakAuthenticationFilter.class);
@@ -61,54 +61,52 @@ public class KeycloakAuthenticationFilter implements Filter {
this.tokenExtractor = tokenExtractor;
}
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {}
-
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
+
final String token = tokenExtractor.getToken(request);
- if (request.getScheme().startsWith("ws") || (token != null && token.startsWith("machine"))) {
+ if (shouldSkipAuthentication(request, token)) {
chain.doFilter(req, res);
return;
- } else {
- final String requestURI = request.getRequestURI();
- if (token == null) {
- LOG.debug("No 'Authorization' header for {}", requestURI);
- send403(res);
- return;
- }
+ }
- Jws jwt;
+ final String requestURI = request.getRequestURI();
+ if (token == null) {
+ LOG.debug("No 'Authorization' header for {}", requestURI);
+ send403(res);
+ return;
+ }
+
+ Jws jwt;
+ try {
+ jwt = Jwts.parser().setSigningKey(getJwtPublicKey(false)).parseClaimsJws(token);
+ LOG.debug("JWT = ", jwt);
+ //OK, we can trust this JWT
+ } catch (SignatureException
+ | NoSuchAlgorithmException
+ | InvalidKeySpecException
+ | IllegalArgumentException e) {
+ //don't trust the JWT!
+ LOG.error("Failed verifying the JWT token", e);
try {
- jwt = Jwts.parser().setSigningKey(getJwtPublicKey(false)).parseClaimsJws(token);
- LOG.debug("JWT = " + jwt.toString());
+ LOG.info("Retrying after updating the public key", e);
+ jwt = Jwts.parser().setSigningKey(getJwtPublicKey(true)).parseClaimsJws(token);
+ LOG.debug("JWT = ", jwt);
//OK, we can trust this JWT
} catch (SignatureException
| NoSuchAlgorithmException
| InvalidKeySpecException
- | IllegalArgumentException e) {
+ | IllegalArgumentException ee) {
//don't trust the JWT!
- LOG.error("Failed verifying the JWT token", e);
- try {
- LOG.info("Retrying after updating the public key", e);
- jwt = Jwts.parser().setSigningKey(getJwtPublicKey(true)).parseClaimsJws(token);
- LOG.debug("JWT = " + jwt.toString());
- //OK, we can trust this JWT
- } catch (SignatureException
- | NoSuchAlgorithmException
- | InvalidKeySpecException
- | IllegalArgumentException ee) {
- //don't trust the JWT!
- LOG.error("Failed verifying the JWT token after public key update", e);
- send403(res);
- return;
- }
+ LOG.error("Failed verifying the JWT token after public key update", e);
+ send403(res);
+ return;
}
- request.setAttribute("token", jwt);
- chain.doFilter(req, res);
}
+ request.setAttribute("token", jwt);
+ chain.doFilter(req, res);
}
private synchronized PublicKey getJwtPublicKey(boolean reset)
@@ -146,7 +144,4 @@ public class KeycloakAuthenticationFilter implements Filter {
HttpServletResponse response = (HttpServletResponse) res;
response.sendError(403);
}
-
- @Override
- public void destroy() {}
}
diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakEnvironmentInitalizationFilter.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakEnvironmentInitalizationFilter.java
index 616c7dd2f2..086bccd116 100644
--- a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakEnvironmentInitalizationFilter.java
+++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/KeycloakEnvironmentInitalizationFilter.java
@@ -18,9 +18,7 @@ import java.io.IOException;
import java.security.Principal;
import javax.inject.Inject;
import javax.inject.Singleton;
-import javax.servlet.Filter;
import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -47,7 +45,7 @@ import org.eclipse.che.commons.subject.SubjectImpl;
* @author Max Shaposhnik (mshaposhnik@redhat.com)
*/
@Singleton
-public class KeycloakEnvironmentInitalizationFilter implements Filter {
+public class KeycloakEnvironmentInitalizationFilter extends AbstractKeycloakFilter {
private final UserManager userManager;
private final AccountManager accountManager;
@@ -63,16 +61,13 @@ public class KeycloakEnvironmentInitalizationFilter implements Filter {
this.tokenExtractor = tokenExtractor;
}
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {}
-
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest) request;
final String token = tokenExtractor.getToken(httpRequest);
- if (request.getScheme().startsWith("ws") || (token != null && token.startsWith("machine"))) {
+ if (shouldSkipAuthentication(httpRequest, token)) {
filterChain.doFilter(request, response);
return;
}
@@ -153,7 +148,4 @@ public class KeycloakEnvironmentInitalizationFilter implements Filter {
}
};
}
-
- @Override
- public void destroy() {}
}
diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java
index 2348669aa2..656abf61b2 100644
--- a/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java
+++ b/plugins/plugin-keycloak/che-plugin-keycloak-server/src/main/java/org/eclipse/che/keycloak/server/deploy/KeycloakServletModule.java
@@ -20,10 +20,12 @@ public class KeycloakServletModule extends ServletModule {
protected void configureServlets() {
bind(KeycloakAuthenticationFilter.class).in(Singleton.class);
- // Not contains '/websocket', /docs/ (for swagger) and not ends with '/ws' or '/eventbus' or '/settings/'
- filterRegex("^(?!.*(/websocket/?|/docs/))(?!.*(/ws/?|/eventbus/?|/settings/?)$).*")
+ // Not contains '/websocket', /docs/ (for swagger) and not ends with '/ws' or '/eventbus' or '/settings/' or '/api/system/state' or '/api/stack/[^/]+/icon/'
+ filterRegex(
+ "^(?!.*(/websocket/?|/docs/))(?!.*(/ws/?|/eventbus/?|/settings/?|/api/system/state/?|/api/stack/[^/]+/icon/?)$).*")
.through(KeycloakAuthenticationFilter.class);
- filterRegex("^(?!.*(/websocket/?|/docs/))(?!.*(/ws/?|/eventbus/?|/settings/?)$).*")
+ filterRegex(
+ "^(?!.*(/websocket/?|/docs/))(?!.*(/ws/?|/eventbus/?|/settings/?|/api/system/state/?|/api/stack/[^/]+/icon/?)$).*")
.through(KeycloakEnvironmentInitalizationFilter.class);
}
}
diff --git a/plugins/plugin-keycloak/che-plugin-keycloak-shared/src/main/java/org/eclipse/che/keycloak/shared/KeycloakConstants.java b/plugins/plugin-keycloak/che-plugin-keycloak-shared/src/main/java/org/eclipse/che/keycloak/shared/KeycloakConstants.java
index 7ccdb79cfa..ef0e82916d 100644
--- a/plugins/plugin-keycloak/che-plugin-keycloak-shared/src/main/java/org/eclipse/che/keycloak/shared/KeycloakConstants.java
+++ b/plugins/plugin-keycloak/che-plugin-keycloak-shared/src/main/java/org/eclipse/che/keycloak/shared/KeycloakConstants.java
@@ -17,18 +17,18 @@ public class KeycloakConstants {
private static final String PRIVATE_PREFIX = "private.";
private static final String KEYCLOAK_SETTINGS_ENDPOINT_PATH = "/keycloak/settings";
- public static final String AUTH_SERVER_URL_SETTING = KEYCLOAK_SETTING_PREFIX + "auth-server-url";
+ public static final String AUTH_SERVER_URL_SETTING = KEYCLOAK_SETTING_PREFIX + "auth_server_url";
public static final String REALM_SETTING = KEYCLOAK_SETTING_PREFIX + "realm";
- public static final String CLIENT_ID_SETTING = KEYCLOAK_SETTING_PREFIX + "client-id";
+ public static final String CLIENT_ID_SETTING = KEYCLOAK_SETTING_PREFIX + "client_id";
public static final String REWRITE_RULE_SETTING =
- KEYCLOAK_SETTING_PREFIX + "redirect-rewrite-rules";
+ KEYCLOAK_SETTING_PREFIX + "redirect_rewrite_rules";
public static final String PRIVATE_REALM_SETTING =
KEYCLOAK_SETTING_PREFIX + PRIVATE_PREFIX + "realm";
public static final String PRIVATE_CLIENT_ID_SETTING =
- KEYCLOAK_SETTING_PREFIX + PRIVATE_PREFIX + "client-id";
+ KEYCLOAK_SETTING_PREFIX + PRIVATE_PREFIX + "client_id";
public static final String PRIVATE_CLIENT_SECRET_SETTING =
- KEYCLOAK_SETTING_PREFIX + PRIVATE_PREFIX + "client-secret";
+ KEYCLOAK_SETTING_PREFIX + PRIVATE_PREFIX + "client_secret";
public static final String OSO_ENDPOINT_SETTING = KEYCLOAK_SETTING_PREFIX + "oso.endpoint";
public static final String PROFILE_ENDPOINT_SETTING =