Re: TomEE 11 - Examples & MP JWT TCK Failures with CXF 4.2.0

Richard Zowalla <[email protected]> Thu, 19 Feb 2026 08:43:51 +0100
Newsgroups gmane.comp.java.openejb.devel
Message-ID <[email protected]>
Hi all,

After some additional feedback from our side, the issue is now resolved =
in current CXF 4.2.1-SNAPSHOT.
I=E2=80=99ve tested the MP JWT TCK + the other failing examples and it =
looks good now. Thanks to Reta for the quick fix.

Gru=C3=9F
Richard


> Am 17.02.2026 um 20:53 schrieb Richard Zowalla <[email protected]>:
>=20
> Reta already replied on the linked PR: =
https://github.com/apache/cxf/pull/2807#discussion_r2818770491
> In short: He will have a look as he did suspect issues.
>=20
> Gru=C3=9F
> Richard
>=20
>> Am 17.02.2026 um 20:41 schrieb David Blevins =
<[email protected]>:
>>=20
>> Sounds good.  Reta is pretty smart.
>>=20
>> It's been a while since I've had my head in the CXF codebase, but if =
AbstractHTTPDestination is created once per endpoint, then caching the =
Principal isn't going to work.
>>=20
>> It does also cache HttpServletRequest, which on its face isn't valid =
unless it's a proxy that uses a thread local to resolve the actual =
HttpServletRequest.  I seem to recall this is the case so @Context =
injection works.
>>=20
>> I'm not sure that same thing is true for Principal.  If Principal can =
be injected via @Context and has similar thread-local-lookup.
>>=20
>> If both HttpServletRequest and Principal are both simply proxies that =
delegate to a thread-local, it could be fine provided the logging is =
tolerant of the scenario where there is no HTTP request.
>>=20
>> Course all that is just a guess -- could be off in left field.
>>=20
>>=20
>> -David
>>=20
>>> On Feb 17, 2026, at 11:20=E2=80=AFAM, Richard Zowalla =
<[email protected]> wrote:
>>>=20
>>> Thanks for your answer, David!
>>>=20
>>> Actually, the commit in CXF is this one: =
https://github.com/apache/cxf/pull/2807/changes#diff-eddf423fac99200bd14e1=
15467dc35809e1855cefdf3bae77f9394b8c050fc94L419 with a totally different =
message "CXF-9116: Remove org.apache.cxf.feature.LoggingFeature=E2=80=9C =
- don=E2=80=99t think removing logging should lead to a behavior change. =
Reta from CXF did comment in his PR for the logging feature removal for =
this change. The following
>>>=20
>>> "some refactoring here: a number of cxf-*-security tests were =
failing due to logging change: apparently when DefaultLogEventMapper is =
called, the underlying HTTP request is already recycled and fails with =
NPE (https://github.com/jetty/jetty.project/issues/12080 ). To mitigate =
that, at least for getUserPrincipal() - capturing principal early.=E2=80=9C=

>>>=20
>>> So I think the change was introduced because of test failures in =
Jetty - I will leave a ping to our thread there, so we might get some =
thoughts by Reta :)
>>>=20
>>> Gru=C3=9F
>>> Richard=20
>>>=20
>>>=20
>>>> Am 17.02.2026 um 18:52 schrieb David Blevins =
<[email protected]>:
>>>>=20
>>>> Thanks for all this detail.   I don't recall the default in MP JWT =
off the top of my head.  Would need to consult the spec, possibly TCK if =
the spec didn't have a clear answer.  Note if the spec isn't clear, let =
me know and I'll update it once we find the answer.
>>>>=20
>>>> I can confirm that calling and caching getPrincipal before an HTTP =
request is read is not valid for any HTTP-based security mechanism; =
basic auth, digest auth, jwt, http session based, soap security, etc, =
etc.  It rules out everything except SSL/TLS certificate-based client =
authentication, which is connection based.
>>>>=20
>>>> Even if they waited till the HTTP message was read and cached for =
the duration of just the request, that's still not really possible =
because of these methods:
>>>>=20
>>>> - HttpServletRequest.login(String username, String password);
>>>> - HttpServletRequest.logout();
>>>> - HttpServletRequest.authenticate(HttpServletResponse response);
>>>>=20
>>>> What they actually do, if anything at all, is completely dependent =
on the underlying security framework.  As is the concept of how long a =
security identity lasts during a request.
>>>>=20
>>>> Sounds like a situation where someone is using security framework X =
which is slow, so some well-intentioned code got added that ultimately =
isn't valid outside of that exact user's scenario.
>>>>=20
>>>> Here's how I would approach resolving this:
>>>>=20
>>>> - Find the commit that added the caching
>>>> - The commit message might tell on itself (x system is slow so =
let's cache)
>>>> - Figure out how they imagined the caching would work: when things =
are removed, added, and in what scope they imagined the cached value was =
valid (request, session, connection, globally).
>>>>=20
>>>> - Analyze a stack trace of the first getPrincipal that's cached.  =
Figure out how we possibly got there as it's not valid.  Even if caching =
is removed, you still can't call getPrincipal without an HTTP request, =
so this has to be solved and fixed.
>>>>=20
>>>>=20
>>>> -David
>>>>=20
>>>>> On Feb 17, 2026, at 6:18=E2=80=AFAM, Richard Zowalla =
<[email protected]> wrote:
>>>>>=20
>>>>> I believe the actual issue is related to the caching mechanism in =
CXF's updated code. Due to this caching, the token validation now =
happens as soon as getPrincipal() is called, which occurs much earlier =
in CXF 4.2.0 than in previous versions.
>>>>>=20
>>>>> As a result, our current TomEE code fails because at that point in =
the request lifecycle, no Authorization header may be present (e.g., for =
@PermitAll endpoints), and the token validation simply fails.
>>>>>=20
>>>>> Additionally, I couldn't find clear guidance in the MP JWT =
specification regarding the default behavior for non-annotated JAX-RS =
methods, i.e., methods without @RolesAllowed, @PermitAll, or @DenyAll.
>>>>>=20
>>>>> It appears this may be vendor-specific. Should the default be:
>>>>> =E2=80=A2 @PermitAll (allow unauthenticated access)?
>>>>> =E2=80=A2 @DenyAll (require authentication)?
>>>>> =E2=80=A2 Something else?
>>>>>=20
>>>>> Gru=C3=9F
>>>>> Richard
>>>>>=20
>>>>>=20
>>>>>=20
>>>>>> Am 17.02.2026 um 14:54 schrieb Richard Zowalla <[email protected]>:
>>>>>>=20
>>>>>> Hi all,
>>>>>>=20
>>>>>> Due to a change in CXF 4.2.0 [1], specifically caching the =
principal instead of looking it up on demand, we are seeing several test =
failures in the MP JWT area - I am now wondering if this a thing CXF =
needs to address or if we need to update our integration. For this =
reason and after some debugging, I would like to get some additional =
context from the past regarding the architecture of our CXF/MP JWT =
integration :)
>>>>>>=20
>>>>>> The failure in question can be reproduced by running =
OrderTest#shouldBeRunning() from the main branch in =
examples/mp-rest-jwt-principal, or by executing parts of the MP JWT TCK, =
which are also failing.
>>>>>>=20
>>>>>> The test calls an endpoint that, according to the test =
assumptions, shouldn=E2=80=99t be protected. It passes on TomEE 10 / CXF =
4.1.5 (which does not cache the principal). The relevant code on our =
side is mainly in MPJWTFilter, especially the MPJWTServletRequestWrapper =
and its use of validate(=E2=80=A6).
>>>>>>=20
>>>>>> Since I=E2=80=99m not an active MP JWT user, I have some (maybe =
dumb?) questions:
>>>>>>=20
>>>>>> According to [2], an application annotated with =
@LoginConfig(authMethod =3D "MP-JWT") requires MP-JWT Access Control =
(potentially for all endpoints?).
>>>>>>=20
>>>>>> If that is the case, the status() method of OrderRestin =
https://github.com/apache/tomee/blob/main/examples/mp-rest-jwt-principal/s=
rc/main/java/org/superbiz/store/rest/OrderRest.java should require a =
JWT, no?
>>>>>>=20
>>>>>> However, we don=E2=80=99t add a token to the REST client in =
https://github.com/apache/tomee/blob/main/examples/mp-rest-jwt-principal/s=
rc/test/java/org/superbiz/store/OrderRestClient.java#L35, so the request =
is sent without a bearer token and fails with a 401.=20
>>>>>>=20
>>>>>> This worked on TomEE 10 / CXF 4.1.5 and earlier.
>>>>>>=20
>>>>>> I suspect some MP JWT TCK failures are caused by the same issue. =
See the build here: =
https://ci-builds.apache.org/job/TomEe/job/master-build-full/org.apache.to=
mee$microprofile-jwt-tck/2071/
>>>>>>=20
>>>>>> Question:
>>>>>>=20
>>>>>> What is the expected behavior? =46rom my reading of the spec, it =
seems this endpoint shouldn=E2=80=99t be invocable without a valid =
token?
>>>>>>=20
>>>>>> Could anyone with more experience in this area (David, JL, =
anyone?) provide some insight?
>>>>>>=20
>>>>>> Thanks and Gru=C3=9F
>>>>>> Richard
>>>>>>=20
>>>>>> [1] =
https://github.com/apache/cxf/pull/2807/changes#diff-eddf423fac99200bd14e1=
15467dc35809e1855cefdf3bae77f9394b8c050fc94L419
>>>>>> [2] =
https://download.eclipse.org/microprofile/microprofile-jwt-auth-2.1/microp=
rofile-jwt-auth-spec-2.1.html#_marking_a_jax_rs_application_as_requiring_m=
p_jwt_access_control
>>>>>>=20
>>>>>=20
>>>>=20
>>>>=20
>>>=20
>>=20
>=20