Skip to content

Should the default getVirtualServerName() return value agree with what JaspiAuthenticatorFactory looks for? #14167

@lrasku

Description

@lrasku

Jetty version(s)
12.1.5

Jetty Environment
ee9 through ee11 by a quick grep of the codebase

HTTP version
Shouldn't matter

Java version/vendor (use: java -version)
openjdk version "21.0.9" 2025-10-21 LTS
OpenJDK Runtime Environment (Red_Hat-21.0.9.0.10-1) (build 21.0.9+10-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-21.0.9.0.10-1) (build 21.0.9+10-LTS, mixed mode, sharing)

OS type/version
AlmaLinux 9.6

Description
The Jakarta Authentication spec says:

A Jakarta Servlet container that implements a version of the Jakarta Servlet specification that defines the getVirtualServerName method on the ServletContext interface, must construct its application context identifiers using a value for hostname that is equivalent to the value returned by calling getVirtualServerName on the ServletContext corresponding to the web application.

So it is indeed tempting to construct the app context identifiers using code like ctx.getVirtualServerName() + " /some/context/path", but unfortunately this won't work on Jetty if the servlet was installed without an explicit virtual host name, because in this scenario getVirtualServerName() returns null, but JaspiAuthenticatorFactory looks for "server".

The easy and obvious fix would be to have getVirtualServerName() return "server" too, but I suspect that would be overturning a lot of precedent and be perhaps misleading besides, but I'm not sure what the alternative would be. Have the docs stress that servlets must be installed with explicit virtual host names?

How to reproduce?
The example project from #14165 can be repurposed for this by changing the "server /" at src/main/java/example/TestServlet.java:49 into ctx.getVirtualServerName()+" /" and observe that authentication fails at http://localhost:9000/test like so:

2025-12-11 01:27:52.378:WARN :oeje10s.ServletChannel:qtp1690716179-95: /test
jakarta.servlet.ServletException: Authentication failed
at org.eclipse.jetty.ee10.servlet.ServletApiRequest.authenticate(ServletApiRequest.java:628)
at example.TestServlet.doGet(TestServlet.java:96)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:752)
at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1620)
at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1554)
at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:868)
at org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:449)
at org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:469)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:546)
at org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:719)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1224)
at org.eclipse.jetty.server.Server.handle(Server.java:197)
at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:720)
at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:412)
at org.eclipse.jetty.server.internal.HttpConnection$FillableCallback.succeeded(HttpConnection.java:1810)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:54)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:1009)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1239)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1194)
at java.base/java.lang.Thread.run(Thread.java:1583)

Due to context path no longer matching.

Metadata

Metadata

Assignees

Labels

QuestionSpecificationFor all industry Specifications (IETF / Servlet / etc)

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions