Cross Origin Filter with embedded Jetty

12,322

Solution 1

A few points:

  • Don't use ServletHandler naked like that. The ServletHandler is an internal class that ServletContextHandler uses.
  • The ServletContextHandler is what provides the needed ServletContext object and state for the various servlets and filters you are using.
  • The ServletContextHandler also provides a place for the overall Context Path declaration
  • The ServletContextHandler is also the place for Welcome Files declaration.
  • Don't use ResourceHandler, when you have DefaultServlet available, its far more capable and feature rich.

Example:

Server server = new Server(httpPort);

// Setup the context for servlets
ServletContextHandler context = new ServletContextHandler();
// Set the context for all filters and servlets
// Required for the internal servlet & filter ServletContext to be sane
context.setContextPath("/");
// The servlet context is what holds the welcome list 
// (not the ResourceHandler or DefaultServlet)
context.setWelcomeFiles(new String[] { "index.html" });

// Add a servlet
context.addServlet(ServerPageRoot.class,"/servlet/*");

// Add the filter, and then use the provided FilterHolder to configure it
FilterHolder cors = context.addFilter(CrossOriginFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
cors.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
cors.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
cors.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD");
cors.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");

// Use a DefaultServlet to serve static files.
// Alternate Holder technique, prepare then add.
// DefaultServlet should be named 'default'
ServletHolder def = new ServletHolder("default", DefaultServlet.class);
def.setInitParameter("resourceBase","./http/");
def.setInitParameter("dirAllowed","false");
context.addServlet(def,"/");

// Create the server level handler list.
HandlerList handlers = new HandlerList();
// Make sure DefaultHandler is last (for error handling reasons)
handlers.setHandlers(new Handler[] { context, new DefaultHandler() });

server.setHandler(handlers);
server.start();

Solution 2

managed to get it working by doing

FilterHolder holder = new FilterHolder(CrossOriginFilter.class);
holder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
holder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD");
holder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
holder.setName("cross-origin");
FilterMapping fm = new FilterMapping();
fm.setFilterName("cross-origin");
fm.setPathSpec("*");
handler.addFilter(holder, fm );

Solution 3

Maybe this will help someone even though it is not a good answer to the original question. I realized that you can easaly enable cross origin request sharing in an embedded jetty instance by manipulating the headers directly in your handler. The response object below is an instance of HttpServletResponse (which is passed to the handler).

Example:

response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "POST, GET");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
Share:
12,322
Mark Trueman
Author by

Mark Trueman

Updated on June 04, 2022

Comments

  • Mark Trueman
    Mark Trueman about 2 years

    I'm trying to get a CrossOriginFilter working with a couple of embedded Jetty servers, both running on our internal network. Both are running servlets, but I need server A's web page to be able to post to server B's servlets. I think I need to add ACCESS_CONTROL_ALLOW_ORIGIN to a CrossOriginFilter but finding out how to do this with an embedded Jetty instance with no web.xml isn't proving to be easy. I get the following error message in the browser when trying to access server b's serlvets

    No 'Access-Control-Allow-Origin' header is present on the requested resource
    

    Im using angularjs to post to the other server's servlets in a controller.

    And here is the code for one of the servers (both are pretty much the same)

    Server server = new Server(httpPort);
    
    ResourceHandler resource_handler = new ResourceHandler();
    resource_handler.setDirectoriesListed(true);
    resource_handler.setWelcomeFiles(new String[] { "index.html" });
    resource_handler.setResourceBase("./http/");
    
    ServletHandler handler = new ServletHandler();
    handler.addServletWithMapping(ServerPageRoot.class, "/servlet/*");
    
    FilterHolder holder = new FilterHolder(CrossOriginFilter.class);
    holder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
    holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
    holder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD");
    holder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
    
    handler.addFilter(holder );
    
    HandlerList handlers = new HandlerList();
    handlers.setHandlers(new Handler[] { resource_handler, handler,new DefaultHandler() });
    server.setHandler(handlers);
    server.start();
    
  • TomTom
    TomTom almost 9 years
    Do you mind updating your answer? Because the code as provided doesn't work (v9.3.4RC0). Firefox tells me CORS header 'Access-Control-Allow-Origin' missing
  • Manuel Kießling
    Manuel Kießling over 7 years
    @joakim-erdfelt I have kind of a meta-question: How does one find out how to approach this solution (except for finding your great answer on SO of course)? I really tried hard to find out myself by reading the Jetty and Servlet documentations, but to no avail. Can you point me in the right direction?
  • user3579222
    user3579222 over 5 years
    could you post the full code (includ. starting jetty?)