New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SWARM-123 - Provide extra configuration for Jolokia #134

Merged
merged 1 commit into from Sep 12, 2016
Jump to file or symbol
Failed to load files and symbols.
+251 −4
Diff settings

Always

Just for now

SWARM-123 - Provide extra configuration for Jolokia

Motivation
----------

Particularly when running Jolokia within the context of a Keycloak-enabled
application, it would be fantastic to be able to also secure the Jolokia
endpoints with Keycloak.

Modifications
-------------

If org.wildfly.swarm:keycloak is present in a -swarm.jar, AND a property
named swarm.jolokia.keycloak.role is set to non-null, then the jolokia.war
is manipulated akin to:

    jolokiaWar.as(Secured.class).protect().withRole( THE_ROLE );

Result
------

In the event Keycloak is available, and a property/config-value is set,
then Jolokia endpoints can be easily secured using the underlying Keycloak
infrastructure.
  • Loading branch information...
bobmcwhirter committed Sep 9, 2016
commit c55447f006fad8fd9042b80ee350274bccc933ab
@@ -0,0 +1,27 @@
package org.wildfly.swarm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.jboss.shrinkwrap.api.Archive;
import org.wildfly.swarm.spi.api.JARArchive;
import org.wildfly.swarm.spi.api.JBossDeploymentStructureAsset;
import org.wildfly.swarm.spi.api.JBossDeploymentStructureContainer;
/**
* @author Bob McWhirter
*/
public class DebugUtils {
public static void dumpJBossDeploymentStructure(Archive archive) {
System.err.println( "--- start jboss-deployment-structure.xml" );
JBossDeploymentStructureAsset asset = archive.as(JARArchive.class).getDescriptorAsset();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(asset.openStream()))) {
reader.lines().forEach(line -> System.err.println(line));
} catch (IOException e) {
e.printStackTrace();
}
System.err.println( "--- end jboss-deployment-structure.xml" );
}
}
Copy path View file
@@ -1,2 +1,4 @@
org.wildfly.swarm.undertow
org.jboss.as.logging
*org.wildfly.swarm.keycloak
Copy path View file
@@ -36,6 +36,12 @@
<artifactId>spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>keycloak</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>staxmapper</artifactId>
@@ -7,4 +7,5 @@
String CONTEXT = "swarm.jolokia.context";
String ACCESS_XML = "swarm.jolokia.access.xml";
String KEYCLOAK_ROLE = "swarm.jolokia.keycloak.role";
}
@@ -0,0 +1,56 @@
package org.wildfly.swarm.jolokia.runtime;
import java.util.function.Consumer;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jboss.shrinkwrap.api.Archive;
import org.wildfly.swarm.jolokia.JolokiaFraction;
import org.wildfly.swarm.jolokia.JolokiaProperties;
import org.wildfly.swarm.keycloak.KeycloakFraction;
import org.wildfly.swarm.keycloak.Secured;
import org.wildfly.swarm.spi.api.Customizer;
import org.wildfly.swarm.spi.runtime.annotations.ConfigurationValue;
import org.wildfly.swarm.spi.runtime.annotations.Pre;
/**
* @author Bob McWhirter
*/
@Pre
@Singleton
public class JolokiaKeycloakCustomizer implements Customizer {
@Inject
KeycloakFraction keycloak;
@Inject
JolokiaFraction jolokia;
@Inject
@ConfigurationValue(JolokiaProperties.KEYCLOAK_ROLE)
String role;
@Override
public void customize() {
if ( this.role == null ) {
return;
}
Consumer<Archive> keycloakPreparer = (archive)->{
archive.as(Secured.class)
.protect()
.withRole(this.role);
};
Consumer<Archive> preparer = this.jolokia.jolokiaWarPreparer();
if ( preparer == null ) {
preparer = keycloakPreparer;
} else {
preparer = preparer.andThen( keycloakPreparer );
}
this.jolokia.prepareJolokiaWar(preparer);
}
}
@@ -0,0 +1,39 @@
package org.wildfly.swarm.jolokia.runtime;
import org.junit.Test;
import org.wildfly.swarm.jolokia.JolokiaFraction;
import static org.fest.assertions.Assertions.assertThat;
/**
* @author Bob McWhirter
*/
public class JolokiaKeycloakCustomizerTest {
@Test
public void testWithoutRole() {
JolokiaFraction jolokia = new JolokiaFraction();
JolokiaKeycloakCustomizer customizer = new JolokiaKeycloakCustomizer();
customizer.jolokia = jolokia;
customizer.customize();
assertThat( jolokia.jolokiaWarPreparer() ).isNull();
}
@Test
public void testWithRole() {
JolokiaFraction jolokia = new JolokiaFraction();
JolokiaKeycloakCustomizer customizer = new JolokiaKeycloakCustomizer();
customizer.jolokia = jolokia;
customizer.role = "admin";
customizer.customize();
assertThat( jolokia.jolokiaWarPreparer() ).isNotNull();
}
}
@@ -20,9 +20,13 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.ByteArrayAsset;
import org.jboss.shrinkwrap.api.importer.ZipImporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.impl.base.ArchiveBase;
import org.jboss.shrinkwrap.impl.base.AssignableBase;
import org.jboss.shrinkwrap.impl.base.importer.zip.ZipImporterImpl;
@@ -70,11 +74,11 @@ public SecuredImpl(ArchiveBase<?> archive) {
if (appArtifact != null) {
try (InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream("_bootstrap/" + appArtifact)) {
ZipImporterImpl importer = new ZipImporterImpl(archive);
importer.importFrom(in);
Node jsonNode = archive.get("keycloak.json");
Archive tmpArchive = ShrinkWrap.create(JavaArchive.class);
tmpArchive.as(ZipImporter.class).importFrom(in);
Node jsonNode = tmpArchive.get("keycloak.json");
if (jsonNode == null) {
jsonNode = archive.get("WEB-INF/keycloak.json");
jsonNode = tmpArchive.get("WEB-INF/keycloak.json");
}
if (jsonNode != null && jsonNode.getAsset() != null) {
Copy path View file
@@ -102,6 +102,7 @@
<module>testsuite-jmx-remote-management</module>
<module>testsuite-jmx-remote-undertow</module>
<module>testsuite-jolokia</module>
<module>testsuite-jolokia-keycloak</module>
<module>testsuite-jpa</module>
<module>testsuite-jpa-mysql</module>
<module>testsuite-jpa-postgresql</module>
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 Red Hat, Inc. and/or its affiliates.
~
~ Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.wildfly.swarm</groupId>
<artifactId>testsuite</artifactId>
<version>2016.10-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.wildfly.swarm</groupId>
<artifactId>testsuite-jolokia-keycloak</artifactId>
<name>Test Suite: Jolokia with Keycloak</name>
<description>Test Suite: Jolokia with Keycloak</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jolokia</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>keycloak</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>arquillian</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,51 @@
package org.wildfly.swarm.jolokia;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.wildfly.swarm.Swarm;
import org.wildfly.swarm.arquillian.CreateSwarm;
import org.wildfly.swarm.spi.api.JARArchive;
import static org.fest.assertions.Assertions.assertThat;
/**
* @author Bob McWhirter
*/
@RunWith(Arquillian.class)
public class JolokiaKeycloakTest {
@Deployment(testable = false)
public static Archive deployment() {
JARArchive deployment = ShrinkWrap.create(JARArchive.class);
deployment.add(EmptyAsset.INSTANCE, "nothing");
return deployment;
}
@CreateSwarm
public static Swarm createSwarm() throws Exception {
System.setProperty( JolokiaProperties.KEYCLOAK_ROLE, "admin" );
return new Swarm();
}
@Test
public void testJolokia() throws Exception {
HttpClientBuilder builder = HttpClientBuilder.create();
CloseableHttpClient client = builder.build();
HttpUriRequest request = new HttpGet("http://localhost:8080/jolokia");
CloseableHttpResponse response = client.execute(request);
assertThat( response.getStatusLine().getStatusCode() ).isEqualTo(403);
}
}
ProTip! Use n and p to navigate between commits in a pull request.