You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by "Markus Jung (Jira)" <ji...@apache.org> on 2026/09/23 18:21:00 UTC
[jira] [Resolved] (TOMEE-4708) OpenID definition EL expressions are evaluated on a shared ELProcessor and fail under concurrent requests (regression of TOMEE-4595)
[ https://issues.apache.org/jira/browse/TOMEE-4708?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Markus Jung resolved TOMEE-4708.
--------------------------------
Resolution: Fixed
> OpenID definition EL expressions are evaluated on a shared ELProcessor and fail under concurrent requests (regression of TOMEE-4595)
> ------------------------------------------------------------------------------------------------------------------------------------
>
> Key: TOMEE-4708
> URL: https://issues.apache.org/jira/browse/TOMEE-4708
> Project: TomEE
> Issue Type: Bug
> Components: TomEE Core Server
> Affects Versions: 11.0.0-M1
> Reporter: Markus Jung
> Assignee: Markus Jung
> Priority: Major
> Time Spent: 20m
> Remaining Estimate: 0h
>
> An {{@OpenIdAuthenticationMechanismDefinition}} with method-call expressions, e.g. {{tokenAutoRefreshExpression = "#
> {cfg.isTrue('...', false)}
> "}}, fails as soon as several requests with an expired access token hit the mechanism at once (typically the burst of parallel {{/jakarta.faces.resource/*}} requests after a page load):
> {noformat}
> jakarta.el.PropertyNotFoundException: ELResolver did not handle type: [false] with property of [isTrue]
> at org.apache.el.parser.AstValue.getValue (AstValue.java:156)
> at jakarta.el.ELProcessor.getValue (ELProcessor.java:62)
> at org.apache.tomee.security.TomEEELInvocationHandler.eval (TomEEELInvocationHandler.java:149)
> at org.apache.tomee.security.cdi.OpenIdAuthenticationMechanism.handleExpiredTokens (OpenIdAuthenticationMechanism.java:215)
> {noformat}
> The message varies between identical requests ({{{}[false]/[isTrue]{}}}, {{{}[null]/[isTrue]{}}}, {{{}[null]/[null]{}}}) and some evaluations silently return wrong values (e.g. {{tokenMinValidity()}} = 0). Affected requests get a 500 and the token refresh never runs.
> h3.
>
> {{TomEEELInvocationHandler.of(Class, Annotation, BeanManager)}} creates one {{ELProcessor}} per definition proxy and uses it from every request thread. {{ELContext}} keeps its "property resolved" flag as a plain field; {{CompositeELResolver.invoke}} clears and re-reads it per evaluation, so concurrent threads corrupt each other's state. {{{}ELProcessor{}}}/{{{}ELContext{}}} are not thread-safe by contract.
>
> TOMEE-4595 (59da9e49d1) made the {{OpenIdAuthenticationMechanismDefinition}} bean {{{}@RequestScoped{}}}, giving each request its own proxy and processor. The Security 4.0 rework (9aaa5454d6, before 11.0.0-M1) introduced {{{}createOpenIdAuthenticationMechanismDefinitionSupplier{}}}, which caches a single proxy in an {{AtomicReference}} for the whole application, and {{OpenIdAuthenticationMechanism.getDefinition()}} prefers that supplier over the injected bean. The request-scoped bean is bypassed on the request path, so the shared processor is back. This shipped in 11.0.0-M1.
> h3. Why the scope change was the wrong fix
> * It patched one consumer instead of the shared processor in {{{}TomEEELInvocationHandler{}}}. Any other code holding the proxy across threads reintroduces the bug, which is what happened. The Basic/LDAP/database/in-memory/{{{}LoginToContinue{}}} proxies were never covered.
> * It made the definition request-bound. {{AutoResolvingProviderMetadata}} caches the discovered provider metadata on the proxy, so a request-scoped proxy re-fetches {{/.well-known/openid-configuration}} from the IdP on every request that reaches it (which {{OpenIdIdentityStore}} does today).
> * It requires an active request context the definition does not otherwise need.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)