[
https://issues.apache.org/jira/browse/WW-5534?focusedWorklogId=959780&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-959780
]
ASF GitHub Bot logged work on WW-5534:
--------------------------------------
Author: ASF GitHub Bot
Created on: 03/Mar/25 11:09
Start Date: 03/Mar/25 11:09
Worklog Time Spent: 10m
Work Description: kusalk commented on code in PR #1237:
URL: https://github.com/apache/struts/pull/1237#discussion_r1977316681
##########
core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java:
##########
@@ -510,9 +519,16 @@ protected StrutsParameter
getParameterAnnotation(AnnotatedElement element) {
return element.getAnnotation(StrutsParameter.class);
}
+ protected Class<?> ultimateClass(Object action) {
+ if (ProxyUtil.isProxy(action)) {
+ return ProxyUtil.ultimateTargetClass(action);
+ }
+ return action.getClass();
+ }
+
protected BeanInfo getBeanInfo(Object action) {
try {
- return Introspector.getBeanInfo(action.getClass());
+ return ognlUtil.getBeanInfo(ultimateClass(action));
Review Comment:
When I implemented this class, I forgot `OgnlUtil` already had a cached
variant of this capability. We are now using that, and resolving any proxies to
ensure annotation detection works as expected.
##########
core/src/main/java/org/apache/struts2/ognl/SecurityMemberAccess.java:
##########
@@ -212,16 +212,17 @@ protected boolean checkAllowlist(Object target, Member
member) {
return true;
}
+ Class<?> targetClass = target != null ? target.getClass() : null;
+
if (!disallowProxyObjectAccess && ProxyUtil.isProxy(target)) {
- // If `disallowProxyObjectAccess` is not set, allow resolving
Hibernate entities to their underlying
- // classes/members. This allows the allowlist capability to
continue working and offer some level of
+ // If `disallowProxyObjectAccess` is not set, allow resolving
Hibernate entities and Spring proxies to their
+ // underlying classes/members. This allows the allowlist
capability to continue working and still offer
// protection in applications where the developer has accepted the
risk of allowing OGNL access to Hibernate
- // entities. This is preferred to having to disable the allowlist
capability entirely.
- Object newTarget = ProxyUtil.getHibernateProxyTarget(target);
- if (newTarget != target) {
- logAllowlistHibernateEntity(target, newTarget);
- target = newTarget;
- member = ProxyUtil.resolveTargetMember(member, newTarget);
+ // entities and Spring proxies. This is preferred to having to
disable the allowlist capability entirely.
+ Class<?> newTargetClass = ProxyUtil.ultimateTargetClass(target);
Review Comment:
We replaced `#getHibernateProxyTarget` with `#ultimateTargetClass` which can
also resolve Spring proxies. This allows the OGNL allowlist to function in the
presence of Spring proxies in applications where
`struts.disallowProxyObjectAccess` has been reverted to `false`.
##########
core/src/test/java/org/apache/struts2/interceptor/parameter/StrutsParameterAnnotationTest.java:
##########
Review Comment:
I added comments for all the other tests in this class as I realised I
didn't name them very well initially
##########
core/src/test/java/org/apache/struts2/interceptor/parameter/StrutsParameterAnnotationTest.java:
##########
@@ -276,6 +384,27 @@ public void publicModelPojo() {
assertThat(threadAllowlist.getAllowlist()).containsExactlyInAnyOrderElementsOf(getParentClasses(Object.class,
Pojo.class));
}
+ /**
+ * Models of ModelDriven actions can be injected without any annotations
on the Action, even when the Action is
+ * proxied.
+ */
+ @Test
+ public void publicModelPojo_proxied() {
+ var proxyFactory = new ProxyFactory(new ModelAction());
Review Comment:
We use the Spring proxy factory to create a CGLIB proxy like would occur
when a transactional proxy is applied to a concrete Action class (like in the
original bug report)
Issue Time Tracking
-------------------
Worklog Id: (was: 959780)
Time Spent: 2h 10m (was: 2h)
> Actions with Spring's @Transactional and ModelDriven
> ----------------------------------------------------
>
> Key: WW-5534
> URL: https://issues.apache.org/jira/browse/WW-5534
> Project: Struts 2
> Issue Type: Bug
> Components: Core Interceptors, Plugin - Spring
> Affects Versions: 7.0.0
> Reporter: Johannes Mayer
> Priority: Minor
> Fix For: 7.1.0
>
> Time Spent: 2h 10m
> Remaining Estimate: 0h
>
> Hi,
> When using the ModelDriven interface, the getModel method has to be annotated
> with {_}@StrutsParameter{_}.
> When Spring decides to wrap an Action object with SpringCGLIB (e.g. when
> annotating a method with {_}@Transactional){_}, one has to add the Package to
> the allowList, so execute can be called. No harm done, just add this to the
> {_}struts.xml{_}:
> {code:java}
> <constant name="struts.allowlist.packageNames" value="your.action.package"/>
> {code}
> The now emerging problem is, that
> _org.apache.struts2.interceptor.parameter.ParametersInterceptor_ is not able
> to map the request parameter to the model, because it is not able to find a
> suitable _getModel_ method. The reason for this is, that the interceptor is
> trying to find the annotation on the SpringCGLIB class, which does not work.
> As a workaround, I can tell the ParameterInterceptor to not need a
> _@StrutsParameter_ annotation, but imo that defeats the purpose of this
> annotation. I am also warned not to make this configuration. I therefore
> assume that this scenario is not desirable.
> {code:java}
> <constant name="struts.parameters.requireAnnotations" value="false" /> {code}
> Spring's AopUtils gives the option the get to the real class:
> _AopUtils.getTargetClass(springCGLIBObject);_
> I created a project to showcase this:
> [https://github.com/sf-JMA/struts7-model-driven/|https://github.com/sf-JMA/struts7-model-driven/tree/main/src/main]
> I added a test
> [https://github.com/sf-JMA/struts7-model-driven/blob/main/src/test/java/com/steadforce/aek/struts7modeldriven/SpringAopVersusModelDrivenTest.java]
> to show the AopUtils method.
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)