Closed rcosne closed 1 month ago
The default location of the WebSocketUpgradeFilter is at the start of the Filter Chain to prevent breaking countless thousands of existing Filters that are not websocket aware.
The normal process of a request in servlet is (loosely) defined like ...
The Jetty approach for WebSocketUpgradeFilter
default is to add WebSocket upgrade support after Servlet Security and Session Handling and before the Filter Chain.
How do you get around this?
Add the WebSocketUpgradeFilter
to your webapp before the webapp is started in any location you want, and before you access the websocket ServerContainer
or attempt to add an endpoint.
You might want to set it up as a ServletContainerInitializer
of your own.
Something like ...
import java.util.EnumSet;
import java.util.Set;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
public class ArbitraryWebsocketUpgradeSCI
implements ServletContainerInitializer
{
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx)
{
FilterRegistration.Dynamic filterDynamic = ctx.addFilter("WebSocketUpgrade", WebSocketUpgradeFilter.class);
filterDynamic.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
filterDynamic.setAsyncSupported(true);
}
}
The default WebSocketUpgradeFilter
is added by the (jetty-11) class org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer
, which can be executed via embedded-jetty or through normal Servlet WebApp initialization of a ServletContainerInitializer
.
Using standard Servlet WebApp descriptors you can execute your SCI before others.
You can control the Jetty JakartaWebSocketServletContainerInitializer
in a few limited ways, such as turning it off via a ServletContext init-param (or attribute) with the key name org.eclipse.jetty.websocket.jakarta
and the value being false
(String or Boolean). But be aware that discovered endpoints will not be automatically added. Your own SCI could add them manually if you wanted, or have your SCI just register what you are interested in ...
import jakarta.websocket.Endpoint;
import jakarta.websocket.server.ServerApplicationConfig;
import jakarta.websocket.server.ServerContainer;
import jakarta.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpointConfig;
@HandlesTypes({ServerApplicationConfig.class, ServerEndpoint.class, Endpoint.class})
public class ArbitraryWebsocketUpgradeSCI
implements ServletContainerInitializer
and add what's discovered to the ServerContainer
yourself.
This isn't a bug in Jetty that needs fixing.
There are ways to work with WebSocketUpgradeFilter
in a non-default way.
Spring-Boot is more than capable of making things work with WebSocketUpgradeFilter
in a consistent way for other spring-boot components.
In fact, I've reached out to spring-boot to see if they are interested in the help.
This issue has been automatically marked as stale because it has been a full year without activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been closed due to it having no activity.
Hi,
I'm currently migrating an application to Spring Boot 3.x which comes with Jetty 11. This application declare a rest controller and a websocket endpoint authenticated via basic auth. But the basic auth does not work anymore on the websocket endpoint.
Sample application: https://github.com/rcosne/ws-test
RestController: http://localhost:8080/test Websocket endpoint: ws://localhost:8080/wstest
It seems that the whole security filter chain is skipped in this case. I've tried to declare a customer filter via @Component, and via a JettyServerCustomizer, in both case, the filter is applied in the rest controller, but not in the websocket endpoint.
I've also tested with Tomcat, then the basic auth works with the websocket.
I've first open an issue on Spring Boot, but they replied the issue is more related to Jetty itself.
Best Regards, Rémy