Skip to content

Commit

Permalink
Merge pull request wildfly#18017 from bstansberry/WFLY-19287
Browse files Browse the repository at this point in the history
[WFLY-19287] Fail boot if EE 11 APIs are used and the security manage…
  • Loading branch information
bstansberry authored Jul 11, 2024
2 parents 1841ad4 + 95e9e2a commit 26f9ece
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 31 deletions.
3 changes: 3 additions & 0 deletions ee/src/main/java/org/jboss/as/ee/logging/EeLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -1224,4 +1224,7 @@ public interface EeLogger extends BasicLogger {

@Message(id = 140, value="Cannot add a HTTP connection which references a null/empty URI")
IllegalArgumentException cannotAddHTTPConnection();

@Message(id = 141, value="Running with a SecurityManager enabled is not allowed in a Jakarta EE 11 or later environment")
OperationFailedException securityManagerNotAllowed();
}
17 changes: 17 additions & 0 deletions ee/src/main/java/org/jboss/as/ee/subsystem/EeSubsystemAdd.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
import org.jboss.as.server.deployment.jbossallxml.JBossAllXmlParserRegisteringProcessor;
import org.jboss.dmr.ModelNode;
import org.jboss.metadata.ear.jboss.JBossAppMetaData;
import org.wildfly.security.manager.WildFlySecurityManager;

/**
* Handler for adding the ee subsystem.
Expand Down Expand Up @@ -111,6 +112,12 @@ public EeSubsystemAdd(final DefaultEarSubDeploymentsIsolationProcessor isolation
this.directoryDependencyProcessor = directoryDependencyProcessor;
}

@Override
public void execute(final OperationContext context, final ModelNode operation) throws OperationFailedException {
checkEEvsSM();
super.execute(context, operation);
}

protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {

for (AttributeDefinition ad : EeSubsystemRootResource.ATTRIBUTES) {
Expand Down Expand Up @@ -227,4 +234,14 @@ protected void execute(DeploymentProcessorTarget processorTarget) {
// installs the service which manages managed executor's hung task periodic termination
new ManagedExecutorHungTasksPeriodicTerminationService().install(context);
}

private static void checkEEvsSM() throws OperationFailedException {
if (WildFlySecurityManager.isChecking()) {
try {
EeSubsystemAdd.class.getClassLoader().loadClass("jakarta.annotation.ManagedBean");
} catch (ClassNotFoundException e) {
throw ROOT_LOGGER.securityManagerNotAllowed();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.test.manual.securitymanager;

import static org.junit.Assert.assertFalse;

import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.as.test.shared.util.AssumeTestGroupUtil;
import org.junit.After;
import org.junit.AssumptionViolatedException;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.wildfly.core.testrunner.ServerControl;

/**
* Tests that starting a server with the SecurityManager enabled fails in an EE11 environment
*/
@RunAsClient()
@RunWith(Arquillian.class)
@ServerControl(manual = true)
public class SecurityManagerRejectedTestCase {

private static final String SERVER_CONFIG_NAME = "forced-security-manager";
@ArquillianResource
private static volatile ContainerController containerController;

@BeforeClass
public static void ee11Only() {

// If we are running in a testsuite execution with the SM explicitly enabled everywhere,
// we can't be expecting servers to fail to boot with the SM.
// So no point going further
AssumeTestGroupUtil.assumeSecurityManagerDisabled();

// Use a missing ManagedBean class as an indicator that we are in an EE 11+ environment.
try {
SecurityManagerRejectedTestCase.class.getClassLoader().loadClass("jakarta.annotation.ManagedBean");
throw new AssumptionViolatedException("Not an EE 11+ environment");
} catch (ClassNotFoundException e) {
// not found means we want the test
}
}

@After
public void ensureContainerStopped() {
// If the test fails, don't leave a running server behind
if (containerController.isStarted(SERVER_CONFIG_NAME)) {
containerController.stop(SERVER_CONFIG_NAME);
}
}

@Test
public void testServerStart() {
assertFalse(containerController.isStarted(SERVER_CONFIG_NAME));
try {
// This config has -secmgr hard coded in its startup args, so it should fail to start
containerController.start(SERVER_CONFIG_NAME);
} catch (Exception ok) {
// good. fall through and confirm the effect of this is the container wasn't started
}
assertFalse(containerController.isStarted(SERVER_CONFIG_NAME));
}
}
19 changes: 19 additions & 0 deletions testsuite/integration/manualmode/src/test/resources/arquillian.xml
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,25 @@
<property name="javaHome">${container.java.home}</property>
</configuration>
</container>

<container qualifier="forced-security-manager" default="false" mode="manual">
<configuration>
<property name="jbossHome">${basedir}/target/wildfly</property>
<property name="javaVmArguments">${server.jvm.args} -Djboss.node.name=default-jbossas</property>
<property name="serverConfig">${jboss.config.file.name:standalone-ha.xml}</property>
<!-- This container is used to check behavior with SM enabled, so we always want it on -->
<property name="jbossArguments">${jboss.args} -secmgr</property>
<property name="allowConnectingToRunningServer">true</property>
<property name="managementAddress">${node0:127.0.0.1}</property>
<property name="managementPort">${as.managementPort:9990}</property>

<!-- AS7-4070 -->
<property name="waitForPorts">${as.debug.port:8787} ${as.managementPort:9990}</property>
<property name="waitForPortsTimeoutInSeconds">8</property>
<property name="modulePath">${basedir}/target/wildfly/modules</property>
<property name="javaHome">${container.java.home}</property>
</configuration>
</container>
</group>

</arquillian>
1 change: 0 additions & 1 deletion testsuite/integration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@
<module>clustering</module>
<module>microprofile</module>
<module>microprofile-tck</module>
<module>secman</module>
<module>elytron</module>
<module>elytron-oidc-client</module>
<module>vdx</module>
Expand Down
30 changes: 0 additions & 30 deletions testsuite/integration/secman/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,36 +131,6 @@
</plugins>
</build>
</profile>

<!-- Test against WildFly Preview dist -->
<profile>
<id>preview.profile</id>
<activation>
<property>
<name>ts.preview</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<!--Re-enable the default surefire execution. -->
<execution>
<id>default-test</id>
<phase>test</phase>
<configuration>
<environmentVariables>
<JBOSS_HOME>${jboss.dist}</JBOSS_HOME>
</environmentVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
7 changes: 7 additions & 0 deletions testsuite/preview/manualmode/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@
<artifactId>wildfly-controller</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.wildfly.core</groupId>
<artifactId>wildfly-core-test-runner</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.wildfly.core</groupId>
<artifactId>wildfly-core-testsuite-shared</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.test.manual.securitymanager;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.as.test.shared.util.AssumeTestGroupUtil;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.wildfly.core.testrunner.ServerControl;

/**
* Tests that starting a server with the SecurityManager enabled fails in an EE11 environment
*/
@RunAsClient()
@RunWith(Arquillian.class)
@ServerControl(manual = true)
public class SecurityManagerRejectedTestCase {

private static final String SERVER_CONFIG_NAME = "forced-security-manager";
@ArquillianResource
private static volatile ContainerController containerController;

@BeforeClass
public static void ee11Only() {

// If we are running in a testsuite execution with the SM explicitly enabled everywhere,
// we can't be expecting servers to fail to boot with the SM.
// So no point going further
AssumeTestGroupUtil.assumeSecurityManagerDisabled();

// Use a missing ManagedBean class as an indicator that we are in an EE 11+ environment.
try {
SecurityManagerRejectedTestCase.class.getClassLoader().loadClass("jakarta.annotation.ManagedBean");
// BES 2024/07/06 -- I've considered supporting ManagedBean in an EE 11+ env; if we do that it would
// likely require making the class available on the test classpath so test deployments can compile.
// If we do that this test should fail, so we can switch to a different mechanism for deciding if it
// should run or not. Check for this when testing WildFly Preview which no longer supports EE 10.
fail("Update this test if we begin putting ManagedBean on the classpath in an EE 11 environment");
} catch (ClassNotFoundException e) {
// not found means we want the test
}
}

@After
public void ensureContainerStopped() {
// If the test fails, don't leave a running server behind
if (containerController.isStarted(SERVER_CONFIG_NAME)) {
containerController.stop(SERVER_CONFIG_NAME);
}
}

@Test
public void testServerStart() {
assertFalse(containerController.isStarted(SERVER_CONFIG_NAME));
try {
// This config has -secmgr hard coded in its startup args, so it should fail to start
containerController.start(SERVER_CONFIG_NAME);
} catch (Exception ok) {
// good. fall through and confirm the effect of this is the container wasn't started
}
assertFalse(containerController.isStarted(SERVER_CONFIG_NAME));
}
}
19 changes: 19 additions & 0 deletions testsuite/preview/manualmode/src/test/resources/arquillian.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@
<property name="javaHome">${container.java.home}</property>
</configuration>
</container>

<container qualifier="forced-security-manager" default="false" mode="manual">
<configuration>
<property name="jbossHome">${basedir}/target/wildfly</property>
<property name="javaVmArguments">${server.jvm.args} -Djboss.node.name=default-jbossas</property>
<property name="serverConfig">${jboss.config.file.name:standalone-ha.xml}</property>
<!-- This container is used to check behavior with SM enabled, so we always want it on -->
<property name="jbossArguments">${jboss.args} -secmgr</property>
<property name="allowConnectingToRunningServer">true</property>
<property name="managementAddress">${node0:127.0.0.1}</property>
<property name="managementPort">${as.managementPort:9990}</property>

<!-- AS7-4070 -->
<property name="waitForPorts">${as.debug.port:8787} ${as.managementPort:9990}</property>
<property name="waitForPortsTimeoutInSeconds">8</property>
<property name="modulePath">${basedir}/target/wildfly/modules</property>
<property name="javaHome">${container.java.home}</property>
</configuration>
</container>
</group>

</arquillian>

0 comments on commit 26f9ece

Please sign in to comment.