This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch WW-5604-cdi-proxy-detection in repository https://gitbox.apache.org/repos/asf/struts.git
commit cf766825f1665db2cdc6fd56723d6d2cf0bc6508 Author: Lukasz Lenart <[email protected]> AuthorDate: Mon Jul 20 14:14:23 2026 +0200 WW-5604 Register CdiProxyService as the active ProxyService Co-Authored-By: Claude Opus 4.8 <[email protected]> --- plugins/cdi/src/main/resources/struts-plugin.xml | 3 + .../cdi/CdiSecurityMemberAccessProxyTest.java | 88 ++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/plugins/cdi/src/main/resources/struts-plugin.xml b/plugins/cdi/src/main/resources/struts-plugin.xml index b0458e940..c69b2073f 100644 --- a/plugins/cdi/src/main/resources/struts-plugin.xml +++ b/plugins/cdi/src/main/resources/struts-plugin.xml @@ -30,4 +30,7 @@ <!-- Make the CDI object factory the automatic default --> <constant name="struts.objectFactory" value="cdi" /> + <bean type="org.apache.struts2.util.ProxyService" name="cdi" class="org.apache.struts2.cdi.CdiProxyService" /> + <constant name="struts.proxyService" value="cdi" /> + </struts> diff --git a/plugins/cdi/src/test/java/org/apache/struts2/cdi/CdiSecurityMemberAccessProxyTest.java b/plugins/cdi/src/test/java/org/apache/struts2/cdi/CdiSecurityMemberAccessProxyTest.java new file mode 100644 index 000000000..6d6a74914 --- /dev/null +++ b/plugins/cdi/src/test/java/org/apache/struts2/cdi/CdiSecurityMemberAccessProxyTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.cdi; + +import ognl.Ognl; +import ognl.OgnlContext; +import org.apache.struts2.ognl.SecurityMemberAccess; +import org.apache.struts2.ognl.StrutsProxyCacheFactory; +import org.apache.struts2.util.ProxyService; +import org.jboss.weld.bootstrap.api.helpers.RegistrySingletonProvider; +import org.jboss.weld.environment.se.Weld; +import org.jboss.weld.environment.se.WeldContainer; +import org.jboss.weld.proxy.WeldClientProxy; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.lang.reflect.Member; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CdiSecurityMemberAccessProxyTest { + + private static WeldContainer container; + + private OgnlContext context; + private SecurityMemberAccess sma; + private ProxiedFooService proxy; + private Member proxyMember; // WeldClientProxy#getMetadata — a proxy member + private Member realMember; // ProxiedFooService#getHello — a real bean member + + @BeforeClass + public static void startContainer() { + container = new Weld().containerId(RegistrySingletonProvider.STATIC_INSTANCE).initialize(); + } + + @AfterClass + public static void stopContainer() { + container.shutdown(); + } + + @Before + public void setUp() throws Exception { + ProxyService proxyService = new CdiProxyService(new StrutsProxyCacheFactory<>("1000", "basic")); + sma = new SecurityMemberAccess(null, null); + sma.setProxyService(proxyService); + + context = (OgnlContext) Ognl.createDefaultContext(null); + proxy = container.select(ProxiedFooService.class).get(); + proxyMember = proxy.getClass().getMethod("getMetadata"); + realMember = proxy.getClass().getMethod("getHello"); + + assertThat(proxy).isInstanceOf(WeldClientProxy.class); // sanity + } + + @Test + public void disallowProxyObjectAccessBlocksWeldProxy() { + sma.useDisallowProxyObjectAccess(Boolean.TRUE.toString()); + // Object-level proxy access disallowed -> any member on the proxy is blocked. + assertThat(sma.isAccessible(context, proxy, realMember, "")).isFalse(); + assertThat(sma.isAccessible(context, proxy, proxyMember, "")).isFalse(); + } + + @Test + public void disallowProxyMemberAccessBlocksWeldProxyMember() { + sma.useDisallowProxyObjectAccess(Boolean.FALSE.toString()); + sma.useDisallowProxyMemberAccess(Boolean.TRUE.toString()); + // The Weld proxy accessor is a proxy member -> blocked. + assertThat(sma.isAccessible(context, proxy, proxyMember, "")).isFalse(); + } +}
