req.authenticate() problems 1.1.0
by Bill Burke
When upgrading from Undertow 1.0.15 to 1.1.0 our
HttpServleRequest.authenticate() unit test is failing. An exception is
being thrown in HttpServletRequestImpl.authenticate() line 416.
Our auth mechanism is being called correctly. It sets the status code
(302) and the Location header within a challenge object. It looks like
exchange.isResponseStarted() is returning false even though my challenge
object is setting up the resposne correctly. Am I supposed to call
exchange.endExchange() or something within my Challenge object? I tried
doing that, but Undertow is now spitting out exception messages:
java.lang.IllegalStateException: UT000002: The response has already been
started
at
io.undertow.server.HttpServerExchange.setResponseCode(HttpServerExchange.java:1246)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:355)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:349)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.transition(SecurityContextImpl.java:349)
at
io.undertow.security.impl.SecurityContextImpl$ChallengeSender.access$300(SecurityContextImpl.java:314)
at
io.undertow.security.impl.SecurityContextImpl.sendChallenges(SecurityContextImpl.java:135)
at
io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:109)
at
io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:99)
at
io.undertow.servlet.spec.HttpServletRequestImpl.authenticate(HttpServletRequestImpl.java:404)
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com
9 years, 11 months
JSESSIONID cookie path empty for root deployments
by arjan tijms
Hi,
For a root deployment, Undertow by default writes the JSESSIONID cookie
with an empty path. I.e. in the response header the following appears:
SET-COOKIE: JSESSIONID=FhgSh... path=; ...
An empty path causes browsers to set the cookie on whatever path was used
for the request URI. In effect, this causes multiple JSESSIONIDs to be
created while browsing through an app deployed to WildFly, and thus
multiple JSESSIONIDs being posted back when other paths are accessed
(leading to many issues).
The cause of this seems to be in
io.undertow.servlet.spec.ServletContextImpl#ServletContextImpl and
io.undertow.servlet.core.DeploymentManagerImpl#handleDeploymentSessionConfig,
where the cookie path is set to deploymentInfo#getContextPath, which in
both cases returns the empty string.
See:
io.undertow.servlet.spec.ServletContextImpl.ServletContextImpl(ServletContainer,
Deployment)
sessionCookieConfig = new SessionCookieConfigImpl(this);
sessionCookieConfig.setPath(deploymentInfo.getContextPath());
and:
io.undertow.servlet.core.DeploymentManagerImpl.handleDeploymentSessionConfig(DeploymentInfo,
ServletContextImpl)
if(sc.getPath() != null) {
sessionCookieConfig.setPath(sc.getPath());
} else {
sessionCookieConfig.setPath(deploymentInfo.getContextPath());
}
I'm not sure if deploymentInfo#getContextPath should indeed return the
empty string for a root deployment or not, but I think setting the cookie
path to the empty string is not really correct and should be "/" in that
case.
Kind regards,
Arjan Tijms
9 years, 12 months
awesome
by Bill Burke
I couldn't believe how easy it was to create an http security proxy for
Keycloak using undertow. Undertow was insanely modular and easy to
piece together how I wanted. Great work guys.
Thanks
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com
9 years, 12 months
Undertow + modules = Wildfly?
by Robert Nikander
Hi,
I’m looking for a minimal webapp server, like Undertow, but I also want JBoss modules (or something with that kind of classloading). Any thoughts on the differences between…
1. Using Wildfly and learning to turn stuff off. I don’t care about most of J2EE.
2. Using only Undertow + the jars for JBoss modules.
Specifically, I’m wondering if there will be much difference in RAM usage, and whether I could still write native Undertow handlers [1] if I go with #1.
Rob
[1] http://undertow.io/documentation/core/undertow-handler-guide.html
10 years
modifyHandshake dilemma
by Ryan Hermanson
Programmatically, I want the ability to reject/deny inbound websocket
connections within my application based on some criteria. The most obvious
approach to me is to implement Configurator and override the
modifyHandshake method. HandshakeResponse only exposes the
SEC_WEBSOCKET_ACCEPT property key. When I set this value as an empty list,
the behavior is not as I was hoping (not sure what I was expecting).
Inline with undertow convention/preference, how can I force a response to
the connecting client endpoint that resembles a 405 or 403?
Thank you,
-Ryan
10 years
PathHandler and HANDLE_404,HANDLE_500
by Efraim Gentil
Hi guys, i’m working on some specs in my app and i’m trying to specify a
404 error handler and 500 error handler in my PathHandler, apparently
that’s not possible, i tried to use default handler as
Handles.path(//MyDefaultHandlerHere), for 404 handler works fine, but what
about 500 error handler ? there is any way to specify this ?
Simple test:
Undertow.builder().addHttpListener( 8080 , "localhost" )
.setHandler(path(new HttpHandler() {
public void handleRequest(HttpServerExchange exchange) throws Exception {
System.out.println( "DEFAULT");
}
})
.addExactPath("/hi", new HttpHandler() {
public void handleRequest(HttpServerExchange exchange) throws Exception {
System.out.println( "HI");
}})
.addExactPath("/hi2", new HttpHandler() {
public void handleRequest(HttpServerExchange exchange) throws Exception {
System.out.println( "HI2");
throw new RuntimeException();
}})
).build();
Maybe in the builder we can have something like
Undertow.builder()
.setNotFoundHandler( notFoundHandlerImpl )
.setServerErrorHandler( serverErrorHandlerImpl )
...
Thanks
--
Atenciosamente,
Efraim Gentil - @efraimgentil <https://twitter.com/efraimgentil>
Github <https://github.com/efraimgentil>
LinkedIn
<http://www.linkedin.com/profile/view?id=215608595&trk=nav_responsive_tab_...>
10 years
ServletContext.getResource() and FileNotFound
by Davide Ungari
Hi everybody,
I'm trying to migrate my webapp from Jetty to Undertow.
The stack is composed by Undertow Guice and Struts2.
I developed the following class to configure undertow:
package com.billdrawer.website.server;
>
> import io.undertow.Undertow;
> import io.undertow.predicate.Predicates;
> import io.undertow.server.HandlerWrapper;
> import io.undertow.server.HttpHandler;
> import io.undertow.server.HttpServerExchange;
> import io.undertow.server.handlers.PathHandler;
> import io.undertow.server.handlers.PredicateHandler;
> import io.undertow.server.handlers.resource.ResourceHandler;
> import io.undertow.servlet.api.ConfidentialPortManager;
> import io.undertow.servlet.api.Deployment;
> import io.undertow.servlet.api.DeploymentInfo;
> import io.undertow.servlet.api.DeploymentManager;
> import io.undertow.servlet.api.FilterInfo;
> import io.undertow.servlet.api.ListenerInfo;
> import io.undertow.servlet.api.LoginConfig;
> import io.undertow.servlet.api.SecurityConstraint;
> import io.undertow.servlet.api.ServletContainer;
> import io.undertow.servlet.api.WebResourceCollection;
>
> import java.net.URL;
> import java.nio.file.Files;
> import java.nio.file.Paths;
> import java.util.EnumSet;
>
> import javax.inject.Inject;
> import javax.inject.Named;
> import javax.servlet.DispatcherType;
> import javax.servlet.ServletContext;
> import javax.servlet.ServletException;
>
> import org.apache.log4j.Logger;
> import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
> import org.keycloak.adapters.AdapterConstants;
> import org.keycloak.adapters.undertow.KeycloakServletExtension;
>
> import com.billdrawer.website.common.Config;
> import com.billdrawer.website.listener.WebsiteServletContextListener;
> import com.google.inject.servlet.GuiceFilter;
>
> public class UndertowServer implements Server {
> private Logger _logger = Logger.getLogger(UndertowServer.class);
> private Undertow _server;
> private DeploymentManager _manager;
> private int _port;
> private String _host;
>
> @Inject
> public UndertowServer((a)Named(Config.STAGE) String stage, @Named(Config.SERVER_HOST) String host, @Named(Config.SERVER_PORT) int port,
> @Named(Config.SERVER_TIMEOUT) int timeout) {
> _port = port;
> _host = host;
>
> DeploymentInfo deploymentInfo = getDeploymentInfo(stage);
>
> ServletContainer _container = ServletContainer.Factory.newInstance();
> _manager = _container.addDeployment(deploymentInfo);
> _manager.deploy();
>
> Deployment deployment = _manager.getDeployment();
>
> KeycloakServletExtension keycloak = new KeycloakServletExtension();
> deploymentInfo.addServletExtension(keycloak);
> deploymentInfo.addInitParameter(AdapterConstants.AUTH_DATA_PARAM_NAME, getKeyloakJson());
> keycloak.handleDeployment(deploymentInfo, _manager.getDeployment().getServletContext());
>
> final ServletContext servletContext = deployment.getServletContext();
> _logger.debug("Context initialized:"+servletContext.getContextPath());
> }
>
> protected String getKeyloakJson() {
> String keycloak = "";
> URL url = getClassLoader().getResource("keycloak.json");
> if (url != null) {
> try {
> byte[] encoded = Files.readAllBytes(Paths.get(url.toURI()));
> keycloak = new String(encoded, "utf-8");
> } catch (Exception e) {
> _logger.error("Can't read keycloak.json", e);
> }
> }
> return keycloak;
> }
>
> protected DeploymentInfo getDeploymentInfo(String stage) {
> final DeploymentInfo deploymentInfo = new DeploymentInfo();
> deploymentInfo.setClassLoader(getClassLoader());
> deploymentInfo.setContextPath("/");
> deploymentInfo.setDefaultEncoding("UTF-8");
> deploymentInfo.setDeploymentName("website.war");
> deploymentInfo.setDisplayName("WebsiteServer");
> deploymentInfo.setUrlEncoding("UTF-8");
>
> deploymentInfo.addListener(new ListenerInfo(WebsiteServletContextListener.class));
>
> FilterInfo guiceFilter = new FilterInfo("GuiceFilter", GuiceFilter.class);
> deploymentInfo.addFilter(guiceFilter);
> for (DispatcherType dispatcher : EnumSet.allOf(DispatcherType.class)) {
> deploymentInfo.addFilterUrlMapping(guiceFilter.getName(), "/*", dispatcher);
> }
>
> FilterInfo strutsPrepareAndExecuteFilter = new FilterInfo("StrutsFilter", StrutsPrepareAndExecuteFilter.class);
> deploymentInfo.addFilter(strutsPrepareAndExecuteFilter);
> for (DispatcherType dispatcher : EnumSet.allOf(DispatcherType.class)) {
> deploymentInfo.addFilterUrlMapping(strutsPrepareAndExecuteFilter.getName(), "/*", dispatcher);
> }
>
> deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {
> @Override
> public HttpHandler wrap(final HttpHandler handler) {
> final ResourceHandler resourceHandler = new ResourceHandler(deploymentInfo.getResourceManager());
> PredicateHandler predicateHandler = new PredicateHandler(Predicates.suffixes(".css",".html",".js"),resourceHandler, handler);
> return predicateHandler;
> }
> });
>
> configureSecurity(deploymentInfo);
>
> return deploymentInfo;
> }
>
> protected void configureSecurity(DeploymentInfo deploymentInfo) {
> deploymentInfo.setLoginConfig(new LoginConfig("KEYCLOAK", "billdrawer"));
> deploymentInfo.setConfidentialPortManager(new ConfidentialPortManager() {
> @Override
> public int getConfidentialPort(HttpServerExchange exchange) {
> return _port;
> }
> });
> SecurityConstraint securityConstraint = new SecurityConstraint();
> WebResourceCollection webResourceCollection = new WebResourceCollection();
> webResourceCollection.addUrlPattern("/dashboard/*");
> securityConstraint.addWebResourceCollection(webResourceCollection);
> securityConstraint.addRoleAllowed("user");
> deploymentInfo.addSecurityConstraint(securityConstraint);
> }
>
> protected ClassLoader getClassLoader() {
> return getClass().getClassLoader();
> }
>
> public void start() {
> _logger.debug("starting...");
> try {
> Undertow.Builder builder = Undertow.builder();
> builder.addHttpListener(_port, _host);
>
> final PathHandler rootHandler = new PathHandler();
> rootHandler.addPrefixPath(_manager.getDeployment().getDeploymentInfo().getContextPath(), _manager.start());
>
> builder.setHandler(rootHandler);
> _server = builder.build();
> _server.start();
> } catch (ServletException e) {
> _logger.error("Unexpected exception", e);
> }
> _logger.info("###START###");
> }
>
> public void stop() {
> _logger.debug("stopping...");
> try {
> _manager.stop();
> _server.stop();
> } catch (ServletException e) {
> _logger.error("Unexpected exception", e);
> }
> _logger.info("###STOP###");
> }
> }
>
> Everything is working until I do not try to load resources from context.
I need some help before rollback to Jetty :(
--
Davide
10 years
AbstractFixedLengthStreamSinkConduit
by Jeff Williams
Hi,
I have written a StreamSinkConduit which buffers content in a pooled
buffer. I am having an issue with AbstractFixedLengthStreamSinkConduit
throwing a FixedLengthUnderflowException exception.
If I have content left in my buffer which I have not yet been able to write
to the next conduit when terminateWrites is called, the exception is
thrown. Even though this content would have been written in the subsequent
call to flush. Shouldn't the bytes remaining be checked after a successful
flush rather than in terminateWrites? Or am I missing something?
For the time being I am flushing my local buffer in terminateWrites, but
this seems wrong!
Jeff
10 years