Add ability to use internal network for keycloak. (#18225)
* Add ability to use internal network for keycloak. Signed-off-by: Oleksandr Andriienko <oandriie@redhat.com>7.24.x
parent
b562d092c6
commit
4100db3053
|
|
@ -119,6 +119,9 @@ che.infra.openshift.oauth_identity_provider=NULL
|
|||
# is used
|
||||
che.keycloak.auth_server_url=http://${CHE_HOST}:5050/auth
|
||||
|
||||
# Internal network service Url to keycloak identity provider server
|
||||
che.keycloak.auth_internal_server_url=NULL
|
||||
|
||||
# Keycloak realm is used to authenticate users
|
||||
# Can be set to NULL only if `che.keycloak.oidcProvider`
|
||||
# is used
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ public class IdentityProviderConfigFactory extends OpenShiftClientConfigFactory
|
|||
+ "</strong> \n"
|
||||
+ "identity provider by visiting the "
|
||||
+ "<a href='"
|
||||
// Here should be used public url. User should have it to make manual actions in the
|
||||
// browser.
|
||||
+ keycloakSettings.get().get(AUTH_SERVER_URL_SETTING)
|
||||
+ "/realms/"
|
||||
+ keycloakSettings.get().get(REALM_SETTING)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@ public class KeycloakJwkProvider implements Provider<JwkProvider> {
|
|||
|
||||
@Inject
|
||||
public KeycloakJwkProvider(KeycloakSettings keycloakSettings) throws MalformedURLException {
|
||||
final String jwksUrl = keycloakSettings.get().get(KeycloakConstants.JWKS_ENDPOINT_SETTING);
|
||||
|
||||
final String jwksUrl =
|
||||
keycloakSettings.getInternalSettings().get(KeycloakConstants.JWKS_ENDPOINT_SETTING);
|
||||
|
||||
if (jwksUrl == null) {
|
||||
throw new ConfigurationException("Jwks endpoint url not found in keycloak settings");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class KeycloakProfileRetriever {
|
|||
KeycloakSettings keycloakSettings, HttpJsonRequestFactory requestFactory) {
|
||||
this.requestFactory = requestFactory;
|
||||
this.keyclockCurrentUserInfoUrl =
|
||||
keycloakSettings.get().get(KeycloakConstants.USERINFO_ENDPOINT_SETTING);
|
||||
keycloakSettings.getInternalSettings().get(KeycloakConstants.USERINFO_ENDPOINT_SETTING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
package org.eclipse.che.multiuser.keycloak.server;
|
||||
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_INTERNAL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.REALM_SETTING;
|
||||
|
||||
import com.google.common.io.CharStreams;
|
||||
|
|
@ -101,7 +101,8 @@ public class KeycloakServiceClient {
|
|||
byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||
final String hash = Base64.getUrlEncoder().encodeToString(check);
|
||||
|
||||
return UriBuilder.fromUri(keycloakSettings.get().get(AUTH_SERVER_URL_SETTING))
|
||||
return UriBuilder.fromUri(
|
||||
keycloakSettings.getInternalSettings().get(AUTH_SERVER_URL_INTERNAL_SETTING))
|
||||
.path("/realms/{realm}/broker/{provider}/link")
|
||||
.queryParam("nonce", nonce)
|
||||
.queryParam("hash", hash)
|
||||
|
|
@ -127,7 +128,8 @@ public class KeycloakServiceClient {
|
|||
throws ForbiddenException, BadRequestException, IOException, NotFoundException,
|
||||
ServerException, UnauthorizedException {
|
||||
String url =
|
||||
UriBuilder.fromUri(keycloakSettings.get().get(AUTH_SERVER_URL_SETTING))
|
||||
UriBuilder.fromUri(
|
||||
keycloakSettings.getInternalSettings().get(AUTH_SERVER_URL_INTERNAL_SETTING))
|
||||
.path("/realms/{realm}/broker/{provider}/token")
|
||||
.build(keycloakSettings.get().get(REALM_SETTING), oauthProvider)
|
||||
.toString();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
*/
|
||||
package org.eclipse.che.multiuser.keycloak.server;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_INTERNAL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.CLIENT_ID_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.FIXED_REDIRECT_URL_FOR_DASHBOARD;
|
||||
|
|
@ -54,13 +56,26 @@ public class KeycloakSettings {
|
|||
private static final Logger LOG = LoggerFactory.getLogger(KeycloakSettings.class);
|
||||
private static final String DEFAULT_USERNAME_CLAIM = "preferred_username";
|
||||
|
||||
/**
|
||||
* Public Keycloak connection settings. It contains information about keycloak api urls and
|
||||
* information required to make Keycloak connection using public domain hostname. This info will
|
||||
* be shared with frontend.
|
||||
*/
|
||||
private final Map<String, String> settings;
|
||||
/**
|
||||
* Internal network Keycloak connection settings. It contains information about keycloak api urls
|
||||
* and information required to make connection using k8s/openshift internal services hostname.
|
||||
* This info will be used only on the Che server side. If using internal network is disabled, then
|
||||
* will be included settings with public domain hostname.
|
||||
*/
|
||||
private final Map<String, String> internalSettings;
|
||||
|
||||
@Inject
|
||||
public KeycloakSettings(
|
||||
@Named("che.api") String cheServerEndpoint,
|
||||
@Nullable @Named(JS_ADAPTER_URL_SETTING) String jsAdapterUrl,
|
||||
@Nullable @Named(AUTH_SERVER_URL_SETTING) String serverURL,
|
||||
@Nullable @Named(AUTH_SERVER_URL_INTERNAL_SETTING) String serverInternalURL,
|
||||
@Nullable @Named(REALM_SETTING) String realm,
|
||||
@Named(CLIENT_ID_SETTING) String clientId,
|
||||
@Nullable @Named(OIDC_PROVIDER_SETTING) String oidcProvider,
|
||||
|
|
@ -70,10 +85,14 @@ public class KeycloakSettings {
|
|||
@Nullable @Named(GITHUB_ENDPOINT_SETTING) String gitHubEndpoint,
|
||||
@Named(USE_FIXED_REDIRECT_URLS_SETTING) boolean useFixedRedirectUrls) {
|
||||
|
||||
serverInternalURL = firstNonNull(serverInternalURL, serverURL);
|
||||
|
||||
if (serverURL == null && oidcProvider == null) {
|
||||
throw new RuntimeException(
|
||||
"Either the '"
|
||||
+ AUTH_SERVER_URL_SETTING
|
||||
+ "'or'"
|
||||
+ AUTH_SERVER_URL_INTERNAL_SETTING
|
||||
+ "' or '"
|
||||
+ OIDC_PROVIDER_SETTING
|
||||
+ "' property should be set");
|
||||
|
|
@ -83,7 +102,7 @@ public class KeycloakSettings {
|
|||
throw new RuntimeException("The '" + REALM_SETTING + "' property should be set");
|
||||
}
|
||||
|
||||
String wellKnownEndpoint = oidcProvider != null ? oidcProvider : serverURL + "/realms/" + realm;
|
||||
String wellKnownEndpoint = firstNonNull(oidcProvider, serverInternalURL + "/realms/" + realm);
|
||||
if (!wellKnownEndpoint.endsWith("/")) {
|
||||
wellKnownEndpoint = wellKnownEndpoint + "/";
|
||||
}
|
||||
|
|
@ -109,10 +128,16 @@ public class KeycloakSettings {
|
|||
LOG.info("openid configuration = {}", openIdConfiguration);
|
||||
|
||||
Map<String, String> settings = Maps.newHashMap();
|
||||
Map<String, String> internalSettings = Maps.newHashMap();
|
||||
settings.put(
|
||||
USERNAME_CLAIM_SETTING, usernameClaim == null ? DEFAULT_USERNAME_CLAIM : usernameClaim);
|
||||
settings.put(CLIENT_ID_SETTING, clientId);
|
||||
settings.put(REALM_SETTING, realm);
|
||||
|
||||
if (serverInternalURL != null) {
|
||||
internalSettings.put(AUTH_SERVER_URL_INTERNAL_SETTING, serverInternalURL);
|
||||
}
|
||||
|
||||
if (serverURL != null) {
|
||||
settings.put(AUTH_SERVER_URL_SETTING, serverURL);
|
||||
settings.put(PROFILE_ENDPOINT_SETTING, serverURL + "/realms/" + realm + "/account");
|
||||
|
|
@ -132,14 +157,24 @@ public class KeycloakSettings {
|
|||
if (tokenEndpoint != null) {
|
||||
settings.put(TOKEN_ENDPOINT_SETTING, tokenEndpoint);
|
||||
}
|
||||
|
||||
String userInfoEndpoint = (String) openIdConfiguration.get("userinfo_endpoint");
|
||||
if (userInfoEndpoint != null) {
|
||||
settings.put(USERINFO_ENDPOINT_SETTING, userInfoEndpoint);
|
||||
if (serverURL != null) {
|
||||
String internalInfoEndpoint = userInfoEndpoint.replace(serverURL, serverInternalURL);
|
||||
internalSettings.put(USERINFO_ENDPOINT_SETTING, internalInfoEndpoint);
|
||||
}
|
||||
}
|
||||
String jwksUriEndpoint = (String) openIdConfiguration.get("jwks_uri");
|
||||
if (jwksUriEndpoint != null) {
|
||||
settings.put(JWKS_ENDPOINT_SETTING, jwksUriEndpoint);
|
||||
if (serverURL != null) {
|
||||
String internalJwksUriEndpoint = jwksUriEndpoint.replace(serverURL, serverInternalURL);
|
||||
internalSettings.put(JWKS_ENDPOINT_SETTING, internalJwksUriEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
settings.put(OSO_ENDPOINT_SETTING, osoEndpoint);
|
||||
settings.put(GITHUB_ENDPOINT_SETTING, gitHubEndpoint);
|
||||
|
||||
|
|
@ -161,9 +196,14 @@ public class KeycloakSettings {
|
|||
settings.put(JS_ADAPTER_URL_SETTING, jsAdapterUrl);
|
||||
|
||||
this.settings = Collections.unmodifiableMap(settings);
|
||||
this.internalSettings = Collections.unmodifiableMap(internalSettings);
|
||||
}
|
||||
|
||||
public Map<String, String> get() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public Map<String, String> getInternalSettings() {
|
||||
return internalSettings;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import org.eclipse.che.commons.env.EnvironmentContext;
|
|||
import org.eclipse.che.multiuser.keycloak.server.KeycloakProfileRetriever;
|
||||
|
||||
/**
|
||||
* Fetches user profile from Keycloack server.
|
||||
* Fetches user profile from Keycloak server.
|
||||
*
|
||||
* @author Max Shaposhnik (mshaposh@redhat.com)
|
||||
* @author Sergii Leshchenko
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ package org.eclipse.che.multiuser.keycloak.server;
|
|||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_INTERNAL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.REALM_SETTING;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
|
@ -67,10 +67,12 @@ public class KeycloakServiceClientTest {
|
|||
public void setUp() throws Exception {
|
||||
keycloakServiceClient = new KeycloakServiceClient(keycloakSettings, jwtParser);
|
||||
Map<String, String> conf = new HashMap<>();
|
||||
conf.put(
|
||||
AUTH_SERVER_URL_SETTING,
|
||||
Map<String, String> confInternal = new HashMap<>();
|
||||
confInternal.put(
|
||||
AUTH_SERVER_URL_INTERNAL_SETTING,
|
||||
RestAssured.baseURI + ":" + RestAssured.port + RestAssured.basePath);
|
||||
conf.put(REALM_SETTING, "che");
|
||||
when(keycloakSettings.getInternalSettings()).thenReturn(confInternal);
|
||||
when(keycloakSettings.get()).thenReturn(conf);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ public class KeycloakConstants {
|
|||
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_INTERNAL_SETTING =
|
||||
KEYCLOAK_SETTING_PREFIX + "auth_internal_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 OIDC_PROVIDER_SETTING = KEYCLOAK_SETTING_PREFIX + "oidc_provider";
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ package org.eclipse.che.multiuser.keycloak.server;
|
|||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static javax.ws.rs.HttpMethod.POST;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.REALM_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.*;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.JsonElement;
|
||||
|
|
@ -76,9 +75,14 @@ public class KeycloakUserRemover {
|
|||
this.keycloakPassword = keycloakPassword;
|
||||
this.requestFactory = requestFactory;
|
||||
if (userRemovalEnabled) {
|
||||
String serverUrl = keycloakSettings.get().get(AUTH_SERVER_URL_SETTING);
|
||||
String serverUrl =
|
||||
keycloakSettings.getInternalSettings().get(AUTH_SERVER_URL_INTERNAL_SETTING);
|
||||
if (serverUrl == null) {
|
||||
throw new ConfigurationException(AUTH_SERVER_URL_SETTING + " is not configured");
|
||||
throw new ConfigurationException(
|
||||
AUTH_SERVER_URL_SETTING
|
||||
+ " or "
|
||||
+ AUTH_SERVER_URL_INTERNAL_SETTING
|
||||
+ " is not configured");
|
||||
}
|
||||
String realm = keycloakSettings.get().get(REALM_SETTING);
|
||||
if (realm == null) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue