[ 
https://issues.apache.org/jira/browse/KNOX-3338?focusedWorklogId=1027915&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1027915
 ]

ASF GitHub Bot logged work on KNOX-3338:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 02/Jul/26 07:44
            Start Date: 02/Jul/26 07:44
    Worklog Time Spent: 10m 
      Work Description: smolnar82 commented on PR #1277:
URL: https://github.com/apache/knox/pull/1277#issuecomment-4863391462

   I'm generally against about these changes because of the use of reflection 
here. Let me explain why.
   
   There are other ways that avoid reflection:
   
   1. **Multi-Release JAR (MRJAR)**: the textbook solution for exactly this. 
Base classes compiled at 17 keep `doAs/getSubject`; a 
`META-INF/versions/18/...` overlay compiled with a JDK 18+ toolchain calls 
`callAs/current` directly and type-safely. No runtime reflection, no 
deprecation suppression on the modern path. Cost: we'll need a JDK 18+ 
available at build (a Maven toolchain) and some pom wiring, which conflicts 
with the current [17,18) enforcer, so that pin would have to relax for the 
build JDK.
   2. **Raise the baseline to JDK 21** and compile with `--release 21,` 
dropping JDK 17. Then just call the new methods directly. Simplest code by far; 
it's a project-policy decision, not a technical blocker.
   
   More important than the reflection debate, the change looks 
incomplete/risky. While analyzing I found things I'd weight higher than the 
reflection question:
   
   1. Only the Shiro path was migrated; the getter/setter now mismatch. 
`SubjectUtils.getCurrentSubject()` now prefers `Subject.current()` on JDK 18+, 
but `Subject.current()` only sees identities established by `callAs`, not by 
**`doAs`!!** (unless the legacy `-Djdk.security.auth.subject.useTL=true` flag 
is set). This PR converts one setter (`ShiroSubjectIdentityAdapter`) to 
`callAs`, but ~10 other auth providers still call `Subject.doAs(...)` directly:
   ```
   AbstractPreAuthFederationFilter, ClientCertFilter, RemoteAuthFilter, 
AnonymousAuthFilter, AbstractIdentityAssertionFilter, 
HadoopAuthFilter/PostFilter, Pac4jIdentityAdapter, AccessTokenFederationFilter, 
AbstractJWTFilter, SpnegoAuthInterceptor, gateway-shell/KnoxSession
   ```
   Consequences on JDK 18+: for any topology using those providers, 
`getCurrentSubject()` via `current()` would return `null` even though the 
request was authenticated (regression risk that appears the moment someone runs 
on 18+, before 23 even matters), and those `doAs` sites still throw 
`UnsupportedOperationException` on JDK 23+, so `KNOX-3338` isn't actually fully 
fixed, only the Shiro path is. The migration needs to be all-or-nothing across 
paired call sites.
   
   2. Exception-wrapping semantics changed. `Subject.doAs` wraps checked 
exceptions in `PrivilegedActionException`; `Subject.callAs` wraps them in 
`CompletionException`. `doSubjectAction` unwraps `InvocationTargetException` 
one level, so the filter chain's `IOException/ServletException` now surfaces 
wrapped in `CompletionException` instead of the old type. Any caller that 
unwraps `PrivilegedActionException` will behave differently. Worth verifying 
the outer filter's error handling.
   
   3. Minor pom hygiene in `gateway-provider-security-shiro/pom.xml`: trailing 
whitespace after the new `</dependency>` and the removed newline at EOF (\ No 
newline at end of file).
   
   Conclusion:
   
   - Reflection works and is defensible, but it's not the only option: MRJAR 
keeps JDK 17 support with zero runtime reflection and no deprecation 
suppression on the modern path; bumping the baseline to 21 is even simpler if 
17 can be dropped.
   - Regardless of reflection vs MRJAR, the bigger issue is that the 
callAs/current pairing is applied inconsistently: migrating only the Shiro 
setter while the getter switches globally risks breaking identity propagation 
on JDK 18+ and leaves the other doAs sites still broken on 23+.
   
   I'll start a `[DISCUSS]` thread on the DEV mailing list about this matter 
and closing this PR for now.




Issue Time Tracking
-------------------

    Worklog Id:     (was: 1027915)
    Time Spent: 0.5h  (was: 20m)

> Java 23+ : java.lang.UnsupportedOperationException: getSubject is not 
> supported
> -------------------------------------------------------------------------------
>
>                 Key: KNOX-3338
>                 URL: https://issues.apache.org/jira/browse/KNOX-3338
>             Project: Apache Knox
>          Issue Type: Improvement
>          Components: KnoxCLI, KnoxShell, Server
>            Reporter: Philip Zampino
>            Priority: Major
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> `javax.security.auth.Subject.getSubject` and `Subject.doAs` were deprecated 
> for removal in JDK 17. The replacement APIs are `Subject.current` and 
> `callAs`. See [JEP 411]([https://openjdk.org/jeps/411]) for background.
> The `Subject.getSubject` API has been "degraded" in JDK 23 to throw 
> `UnsupportedOperationException` if not running with the option to allow a 
> SecurityManager. In a future JDK release, the `Subject.getSubject` API will 
> be degraded further to throw`UnsupportedOperationException` unconditionally.
> {noformat}
> Caused by: java.lang.UnsupportedOperationException: getSubject is not 
> supported
>         at javax.security.auth.Subject.getSubject(Subject.java:277) ~[?:?]
>         at 
> org.apache.knox.gateway.security.SubjectUtils.getCurrentSubject(SubjectUtils.java:41)
>  ~[gateway-spi-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter.doFilter(CommonIdentityAssertionFilter.java:226)
>  
> ~[gateway-provider-identity-assertion-common-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:391) 
> ~[gateway-server-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:305) 
> ~[gateway-server-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter$CallableChain$1.run(ShiroSubjectIdentityAdapter.java:136)
>  ~[gateway-provider-security-shiro-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter$CallableChain$1.run(ShiroSubjectIdentityAdapter.java:133)
>  ~[gateway-provider-security-shiro-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> jdk.internal.vm.ScopedValueContainer.callWithoutScope(ScopedValueContainer.java:162)
>  ~[?:?]
>         at 
> jdk.internal.vm.ScopedValueContainer.call(ScopedValueContainer.java:147) 
> ~[?:?]
>         at java.lang.ScopedValue$Carrier.call(ScopedValue.java:419) ~[?:?]
>         at javax.security.auth.Subject.callAs(Subject.java:331) ~[?:?]
>         at javax.security.auth.Subject.doAs(Subject.java:440) ~[?:?]
>         at 
> org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter$CallableChain.call(ShiroSubjectIdentityAdapter.java:214)
>  ~[gateway-provider-security-shiro-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter$CallableChain.call(ShiroSubjectIdentityAdapter.java:119)
>  ~[gateway-provider-security-shiro-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
>  ~[shiro-core-1.13.0.jar:1.13.0]
>         at 
> org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
>  ~[shiro-core-1.13.0.jar:1.13.0]
>         at 
> org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
>  ~[shiro-core-1.13.0.jar:1.13.0]
>         at 
> org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter.doFilter(ShiroSubjectIdentityAdapter.java:116)
>  ~[gateway-provider-security-shiro-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:391) 
> ~[gateway-server-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.knox.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:305) 
> ~[gateway-server-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
>         at 
> org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
>  ~[shiro-web-1.13.0.jar:1.13.0]
>         at 
> org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) 
> ~[shiro-web-1.13.0.jar:1.13.0]
>         at 
> org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
>  ~[shiro-web-1.13.0.jar:1.13.0]
>         ... 74 more{noformat}
> Knox must migrate to the newer version of the Subject class.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to