From cbaf94e69c941a5a1c7272857be8e8330f3cccd5 Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Wed, 4 Mar 2020 10:49:25 +0200 Subject: [PATCH] Apply OpenShift OAuth provider (#15963) --- assembly/assembly-wsmaster-war/pom.xml | 4 + .../che/api/deploy/WsMasterModule.java | 3 + .../webapp/WEB-INF/classes/che/che.properties | 5 + .../helm/che/templates/configmap.yaml | 4 + deploy/kubernetes/helm/che/values.yaml | 4 + .../templates/che-server-template.yaml | 26 ++++- pom.xml | 5 + wsmaster/che-core-api-auth-openshift/pom.xml | 55 +++++++++++ .../oauth/OpenShiftOAuthAuthenticator.java | 94 +++++++++++++++++++ .../security/oauth/OpenShiftOAuthModule.java | 29 ++++++ wsmaster/pom.xml | 1 + 11 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 wsmaster/che-core-api-auth-openshift/pom.xml create mode 100644 wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthAuthenticator.java create mode 100644 wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthModule.java diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index 511cbb3ed68..764bfa4b650 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -111,6 +111,10 @@ org.eclipse.che.core che-core-api-auth + + org.eclipse.che.core + che-core-api-auth-openshift + org.eclipse.che.core che-core-api-auth-shared diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index a5d5af727ac..b4c37739acf 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -88,6 +88,7 @@ import org.eclipse.che.security.PasswordEncryptor; import org.eclipse.che.security.oauth.EmbeddedOAuthAPI; import org.eclipse.che.security.oauth.OAuthAPI; +import org.eclipse.che.security.oauth.OpenShiftOAuthModule; import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfraModule; import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructure; import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment; @@ -264,6 +265,8 @@ protected void configure() { install(new TracingMetricsModule()); } install(new ExecutorWrapperModule()); + + install(new OpenShiftOAuthModule()); } private void configureSingleUserMode(Map persistenceProperties) { diff --git a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties index 1d75ac9229c..17a873328c5 100644 --- a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties +++ b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties @@ -183,6 +183,11 @@ che.oauth.github.authuri= https://github.com/login/oauth/authorize che.oauth.github.tokenuri= https://github.com/login/oauth/access_token che.oauth.github.redirecturis= http://localhost:${CHE_PORT}/api/oauth/callback +# Configuration of OpenShift OAuth client. Used to obtain OpenShift OAuth token. +che.oauth.openshift.clientid=NULL +che.oauth.openshift.clientsecret=NULL +che.oauth.openshift.oauth_endpoint= NULL +che.oauth.openshift.verify_token_url= NULL ### Internal diff --git a/deploy/kubernetes/helm/che/templates/configmap.yaml b/deploy/kubernetes/helm/che/templates/configmap.yaml index 7aad45fc4e1..cf856d5e5f1 100644 --- a/deploy/kubernetes/helm/che/templates/configmap.yaml +++ b/deploy/kubernetes/helm/che/templates/configmap.yaml @@ -68,6 +68,10 @@ data: CHE_MULTIUSER: {{ .Values.global.multiuser | quote }} CHE_OAUTH_GITHUB_CLIENTID: {{ .Values.global.gitHubClientID | quote}} CHE_OAUTH_GITHUB_CLIENTSECRET: {{ .Values.global.gitHubClientSecret | quote}} + CHE_OAUTH_OPENSHIFT_CLIENTID: {{ .Values.global.openShiftClientID | quote}} + CHE_OAUTH_OPENSHIFT_CLIENTSECRET: {{ .Values.global.openShiftClientSecret | quote}} + CHE_OAUTH_OPENSHIFT_OAUTH__ENDPOINT: {{ .Values.global.openShiftOAuthEndpoint | quote}} + CHE_OAUTH_OPENSHIFT_VERIFY__TOKEN__URL: {{ .Values.global.openShiftVerifyTokenUrl | quote}} JAVA_OPTS: "-XX:MaxRAMFraction=2 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Dsun.zip.disableMemoryMapping=true -Xms20m " CHE_WORKSPACE_AUTO_START: "false" {{- if .Values.global.tls.enabled }} diff --git a/deploy/kubernetes/helm/che/values.yaml b/deploy/kubernetes/helm/che/values.yaml index e1fd7855a47..4054f503b9f 100644 --- a/deploy/kubernetes/helm/che/values.yaml +++ b/deploy/kubernetes/helm/che/values.yaml @@ -58,6 +58,10 @@ global: gitHubClientID: "" gitHubClientSecret: "" + openShiftClientID: "" + openShiftClientSecret: "" + openShiftOAuthEndpoint: "" + openShiftVerifyTokenUrl: "" # Possible values: common, per-workspace, unique cheWorkspacesPVCStrategy: "common" pvcClaim: "1Gi" diff --git a/deploy/openshift/templates/che-server-template.yaml b/deploy/openshift/templates/che-server-template.yaml index bab32c0337e..eb8925dfe80 100644 --- a/deploy/openshift/templates/che-server-template.yaml +++ b/deploy/openshift/templates/che-server-template.yaml @@ -140,6 +140,14 @@ objects: value: "${CHE_OAUTH_GITHUB_CLIENTID}" - name: CHE_OAUTH_GITHUB_CLIENTSECRET value: "${CHE_OAUTH_GITHUB_CLIENTSECRET}" + - name: CHE_OAUTH_OPENSHIFT_CLIENTID + value: "${CHE_OAUTH_OPENSHIFT_CLIENTID}" + - name: CHE_OAUTH_OPENSHIFT_CLIENTSECRET + value: "${CHE_OAUTH_OPENSHIFT_CLIENTSECRET}" + - name: CHE_OAUTH_OPENSHIFT_OAUTH__ENDPOINT + value: "${CHE_OAUTH_OPENSHIFT_OAUTH__ENDPOINT}" + - name: CHE_OAUTH_OPENSHIFT_VERIFY__TOKEN__URL + value: "${CHE_OAUTH_OPENSHIFT_VERIFY__TOKEN__URL}" - name: JAVA_OPTS value: "-XX:MaxRAMFraction=2 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 @@ -341,7 +349,23 @@ parameters: value: '' - name: CHE_OAUTH_GITHUB_CLIENTSECRET displayName: GitHub Client Secret - description: GitHub OAuth app client servet. Applicable to Che single user only! + description: GitHub OAuth app client secret. Applicable to Che single user only! + value: '' +- name: CHE_OAUTH_OPENSHIFT_CLIENTID + displayName: OpenShift Client ID + description: OpenShift OAuth app client ID. Applicable to Che single user only! + value: '' +- name: CHE_OAUTH_OPENSHIFT_CLIENTSECRET + displayName: OpenShift Client Secret + description: OpenShift OAuth app client secret. Applicable to Che single user only! + value: '' +- name: CHE_OAUTH_OPENSHIFT_OAUTH__ENDPOINT + displayName: OpenShift oauth endpoint + description: OpenShift oauth endpoint. Applicable to Che single user only! + value: '' +- name: CHE_OAUTH_OPENSHIFT_VERIFY__TOKEN__URL + displayName: OpenShift verify token url + description: A url that requests some OpenShift resource. Is used to verify the OpenShift token. Applicable to Che single user only! value: '' - name: CHE_WORKSPACE_PLUGIN__REGISTRY__URL displayName: Eclipse Che plugin registry URL diff --git a/pom.xml b/pom.xml index 5ae7676b507..98c9e7c85b0 100644 --- a/pom.xml +++ b/pom.xml @@ -130,6 +130,11 @@ che-core-api-auth-github ${che.version} + + org.eclipse.che.core + che-core-api-auth-openshift + ${che.version} + org.eclipse.che.core che-core-api-auth-shared diff --git a/wsmaster/che-core-api-auth-openshift/pom.xml b/wsmaster/che-core-api-auth-openshift/pom.xml new file mode 100644 index 00000000000..6feebbea022 --- /dev/null +++ b/wsmaster/che-core-api-auth-openshift/pom.xml @@ -0,0 +1,55 @@ + + + + 4.0.0 + + che-master-parent + org.eclipse.che.core + 7.10.0-SNAPSHOT + + che-core-api-auth-openshift + jar + Che Core :: API :: Authentication OpenShift + + + com.google.guava + guava + + + com.google.http-client + google-http-client + + + com.google.inject + guice + + + javax.inject + javax.inject + + + org.eclipse.che.core + che-core-api-auth + + + org.eclipse.che.core + che-core-api-auth-shared + + + org.eclipse.che.core + che-core-commons-annotations + + + diff --git a/wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthAuthenticator.java b/wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthAuthenticator.java new file mode 100644 index 00000000000..a940ec24cd3 --- /dev/null +++ b/wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthAuthenticator.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.security.oauth; + +import static com.google.common.base.Strings.isNullOrEmpty; + +import com.google.api.client.util.store.MemoryDataStoreFactory; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import org.eclipse.che.api.auth.shared.dto.OAuthToken; +import org.eclipse.che.commons.annotation.Nullable; +import org.eclipse.che.security.oauth.shared.User; + +/** + * OAuth authentication for OpenShift. + * + * @author Igor Vinokur + */ +@Singleton +public class OpenShiftOAuthAuthenticator extends OAuthAuthenticator { + private final String verifyTokenUrl; + + @Inject + public OpenShiftOAuthAuthenticator( + @Nullable @Named("che.oauth.openshift.clientid") String clientId, + @Nullable @Named("che.oauth.openshift.clientsecret") String clientSecret, + @Nullable @Named("che.oauth.openshift.oauth_endpoint") String oauthEndpoint, + @Nullable @Named("che.oauth.openshift.verify_token_url") String verifyTokenUrl, + @Named("che.api") String apiEndpoint) + throws IOException { + this.verifyTokenUrl = verifyTokenUrl; + String[] redirectUrl = {apiEndpoint + "/oauth/callback"}; + if (!isNullOrEmpty(clientId) && !isNullOrEmpty(clientSecret) && !isNullOrEmpty(oauthEndpoint)) { + oauthEndpoint = oauthEndpoint.endsWith("/") ? oauthEndpoint : oauthEndpoint + "/"; + configure( + clientId, + clientSecret, + redirectUrl, + oauthEndpoint + "oauth/authorize", + oauthEndpoint + "oauth/token", + new MemoryDataStoreFactory()); + } + } + + @Override + public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException { + throw new OAuthAuthenticationException("not supported"); + } + + @Override + public final String getOAuthProvider() { + return "openshift"; + } + + @Override + public OAuthToken getToken(String userId) throws IOException { + final OAuthToken token = super.getToken(userId); + // Check if the token is valid for requests. + if (!(token == null || token.getToken() == null || token.getToken().isEmpty())) { + HttpURLConnection http = null; + try { + http = (HttpURLConnection) new URL(verifyTokenUrl).openConnection(); + http.setInstanceFollowRedirects(false); + http.setRequestMethod("GET"); + http.setRequestProperty("Authorization", "Bearer " + token.getToken()); + http.setRequestProperty("Accept", "application/json"); + + if (http.getResponseCode() == 401) { + return null; + } + } finally { + if (http != null) { + http.disconnect(); + } + } + + return token; + } + return null; + } +} diff --git a/wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthModule.java b/wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthModule.java new file mode 100644 index 00000000000..eb95fcf0206 --- /dev/null +++ b/wsmaster/che-core-api-auth-openshift/src/main/java/org/eclipse/che/security/oauth/OpenShiftOAuthModule.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.security.oauth; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; + +/** + * Setup OpenShiftOAuthAuthenticator in guice container. + * + * @author Igor Vinokur + */ +public class OpenShiftOAuthModule extends AbstractModule { + @Override + protected void configure() { + Multibinder oAuthAuthenticators = + Multibinder.newSetBinder(binder(), OAuthAuthenticator.class); + oAuthAuthenticators.addBinding().to(OpenShiftOAuthAuthenticator.class); + } +} diff --git a/wsmaster/pom.xml b/wsmaster/pom.xml index 7d11e6ede2c..8d4cad7f373 100644 --- a/wsmaster/pom.xml +++ b/wsmaster/pom.xml @@ -28,6 +28,7 @@ che-core-api-auth-shared che-core-api-auth che-core-api-auth-github + che-core-api-auth-openshift che-core-api-workspace-shared che-core-api-workspace che-core-api-workspace-activity