Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

Commit

Permalink
Add the customized valve to enable bypassing Keycloak authentication
Browse files Browse the repository at this point in the history
Signed-off-by: David Festal <dfestal@redhat.com>
  • Loading branch information
davidfestal committed Jul 6, 2017
1 parent 5851878 commit 37f1862
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
-->
<Context allowCasualMultipartParsing="true">
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve"/>
+ <Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
+ <Valve className="com.redhat.che.valve.UserAuthValve"/>
</Context>
22 changes: 22 additions & 0 deletions builds/fabric8-che/assembly/assembly-main/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
<artifactId>fabric8-ide-stacks</artifactId>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.redhat.che</groupId>
<artifactId>user-auth-valve</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down Expand Up @@ -100,6 +104,24 @@
</artifactItems>
</configuration>
</execution>
<execution>
<id>package-user-auth-valve</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.redhat.che</groupId>
<artifactId>user-auth-valve</artifactId>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/keycloak</outputDirectory>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Expand Down
1 change: 1 addition & 0 deletions builds/fabric8-che/assembly/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<module>assembly-ide-war</module>
<module>assembly-wsmaster-war</module>
<module>assembly-main</module>
<module>user-auth-valve</module>
</modules>
<build>
<pluginManagement>
Expand Down
37 changes: 37 additions & 0 deletions builds/fabric8-che/assembly/user-auth-valve/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0"?>
<!--
Copyright (c) 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
-->

<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>fabric8-ide-assembly-parent</artifactId>
<groupId>com.redhat.che</groupId>
<version>@redhat.che.version@</version>
</parent>
<artifactId>user-auth-valve</artifactId>
<name>user-auth-valve</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat8-adapter</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.redhat.che.valve;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve;

public class UserAuthValve extends KeycloakAuthenticatorValve {

private static final String KEYCLOAK_SETTINGS_ENDPOINT = "http://che-host:8080/api/keycloak/settings";
private static final Pattern DISABLED_SETTING_PATTERN = Pattern.compile(".*\"che\\.keycloak\\.disabled\":\"([^ \"]+)\".*");
private static final Log LOG = LogFactory.getLog(UserAuthValve.class);

@Override
public boolean authenticate(Request request, HttpServletResponse response) throws IOException {
if (isKeycloakDisabled()) {
LOG.info("Keycloak is disabled => Bypassing authentification");
GenericPrincipal genericPrincipal = new GenericPrincipal("developer", "developer", Arrays.asList("developer"));
request.setUserPrincipal(genericPrincipal);
request.setAuthType(HttpServletRequest.BASIC_AUTH);
return true;
}

return super.authenticate(request, response);
}


public boolean isKeycloakDisabled() {
URL url;
HttpURLConnection conn;
try {
url = new URL(KEYCLOAK_SETTINGS_ENDPOINT);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
response.append(line);
}
LOG.info("Keycloak settings: " + response);
Matcher matcher = DISABLED_SETTING_PATTERN.matcher(response.toString());
if (matcher.matches()) {
String value = matcher.group(1);
return "true".equals(value);
}
return false;

} catch (IOException e) {
LOG.error("Exception during Keycloak settings retrieval", e);
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,23 @@ public KeycloakTokenProvider(@Nullable @Named("che.keycloak.github.endpoint") St

/**
* Return GitHub access token based on Keycloak token
*
*
* <p>
* Note: valid response from keycloak endpoint:
* Note: valid response from keycloak endpoint:
* access_token=token&scope=scope&token_type=bearer
* </p>
*
*
* @param keycloakToken
*
* @return GitHub access token
* @throws IOException
* @throws BadRequestException
* @throws ConflictException
* @throws NotFoundException
* @throws ForbiddenException
* @throws UnauthorizedException
* @throws ServerException
*
*
* @return GitHub access token
* @throws IOException
* @throws BadRequestException
* @throws ConflictException
* @throws NotFoundException
* @throws ForbiddenException
* @throws UnauthorizedException
* @throws ServerException
*
*/
public String obtainGitHubToken(String keycloakToken) throws ServerException, UnauthorizedException, ForbiddenException, NotFoundException, ConflictException, BadRequestException, IOException {
String responseBody = getResponseBody(gitHubEndpoint, keycloakToken);
Expand All @@ -77,29 +77,33 @@ public String obtainGitHubToken(String keycloakToken) throws ServerException, Un

/**
* Return OpenShift online token based on Keycloak token
*
*
* <p>
* Note: valid response from keycloak endpoint:
* Note: valid response from keycloak endpoint:
* {"access_token":"token","expires_in":86400,"scope":"user:full","token_type":"Bearer"}
* </p>
*
*
* @param keycloakToken
*
* @return OpenShift online token
* @throws BadRequestException
* @throws ConflictException
* @throws NotFoundException
* @throws ForbiddenException
* @throws UnauthorizedException
* @throws ServerException
*
*
* @return OpenShift online token
* @throws BadRequestException
* @throws ConflictException
* @throws NotFoundException
* @throws ForbiddenException
* @throws UnauthorizedException
* @throws ServerException
*
*/
public String obtainOsoToken(String keycloakToken) throws IOException, ServerException, UnauthorizedException, ForbiddenException, NotFoundException, ConflictException, BadRequestException {
String responseBody = getResponseBody(openShiftEndpoint, keycloakToken);
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree(responseBody);
JsonNode token = json.get(ACCESS_TOKEN);
return token.asText();
if (token != null) {
return token.asText();
} else {
return null;
}
}

private String getResponseBody(final String endpoint, final String keycloakToken) throws ServerException, UnauthorizedException, ForbiddenException, NotFoundException, ConflictException, BadRequestException, IOException {
Expand Down
11 changes: 11 additions & 0 deletions builds/fabric8-che/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@
<version>${rh.che.plugins.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.redhat.che</groupId>
<artifactId>user-auth-valve</artifactId>
<version>@redhat.che.version@</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.eclipse.che</groupId>
<artifactId>assembly-ide-war</artifactId>
Expand Down Expand Up @@ -150,6 +156,11 @@
<artifactId>keycloak-servlet-filter-adapter</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat8-adapter</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat8-adapter-dist</artifactId>
Expand Down

0 comments on commit 37f1862

Please sign in to comment.