Cross Origin Filter with embedded Jetty

前端 未结 4 1229
小蘑菇
小蘑菇 2020-12-10 20:49

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\

相关标签:
4条回答
  • 2020-12-10 20:53

    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");
    
    0 讨论(0)
  • 2020-12-10 20:58

    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();
    
    0 讨论(0)
  • 2020-12-10 20:59

    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 );
    
    0 讨论(0)
  • 2020-12-10 21:04

    I tried all the way of above answers and other similar ones. But always, I came across same error message.

    Finally I reach a correct answer for my situation. I use Jersey with Jetty and I am not using web.xml. If you try all methods and you don't enable the CORS support, maybe you can try this solution below.

    1. First, define a filter (you can define another one which directly implements Filter class)

    import java.io.IOException;
    
    import javax.ws.rs.container.ContainerRequestContext;
    import javax.ws.rs.container.ContainerRequestFilter;
    import javax.ws.rs.container.ContainerResponseContext;
    import javax.ws.rs.container.ContainerResponseFilter;
    import javax.ws.rs.core.Response;
    
    public class CorsFilter implements ContainerRequestFilter, ContainerResponseFilter {
    
        private static boolean isPreflightRequest(ContainerRequestContext request) {
            return request.getHeaderString("Origin") != null && request.getMethod().equalsIgnoreCase("OPTIONS");
        }
    
        @Override
        public void filter(ContainerRequestContext request) throws IOException {
    
            // If it's a preflight request, we abort the request 
            if (isPreflightRequest(request)) {
                request.abortWith(Response.ok().build());
                return;
            }
        }
    
        @Override
        public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException {
    
            // if there is no Origin header, we don't do anything.
            if (request.getHeaderString("Origin") == null) {
                return;
            }
    
            // If it is a preflight request, then we add all
            // the CORS headers here.
            if (isPreflightRequest(request)) {
                response.getHeaders().add("Access-Control-Allow-Credentials", "true");
                response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
                response.getHeaders().add("Access-Control-Allow-Headers",
                        // Whatever other non-standard/safe headers (see list above)
                        // you want the client to be able to send to the server,
                        // put it in this list. And remove the ones you don't want.
                        "X-Requested-With,Content-Type,Content-Length,Authorization,"
                                + "Accept,Origin,Cache-Control,Accept-Encoding,Access-Control-Request-Headers,"
                                + "Access-Control-Request-Method,Referer,x-csrftoken,ClientKey");
            }
    
            response.getHeaders().add("Access-Control-Allow-Origin", "*");
        }
    }
    
    1. Register this filter to resource config

    import java.io.IOException;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.ServerConnector;
    import org.eclipse.jetty.servlet.DefaultServlet;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    import org.glassfish.jersey.server.ResourceConfig;
    import org.glassfish.jersey.servlet.ServletContainer;
    
    public class AppServer {
    
        public static void main(String[] args) throws Exception {
    
            Server jettyServer = new Server();
    
            // Add port
            ServerConnector jettyServerConnector = new ServerConnector(jettyServer);
            jettyServerConnector.setPort(Integer.parseInt("9090"));
            jettyServer.addConnector(jettyServerConnector);
    
            // Define main servlet context handler
            ServletContextHandler jettyServletContextHandler = new ServletContextHandler();
            jettyServletContextHandler.setContextPath("/service");
    
            // Define main resource (webapi package) support
            ResourceConfig webapiResourceConfig = new ResourceConfig();
            webapiResourceConfig.packages("com.example.service");
            ServletContainer webapiServletContainer = new ServletContainer(webapiResourceConfig);
            ServletHolder webapiServletHolder = new ServletHolder(webapiServletContainer);
            jettyServletContextHandler.addServlet(webapiServletHolder, "/webapi/*");
    
            // Add Cors Filter
            webapiResourceConfig.register(CorsFilter.class, 1);
    
            try {
                jettyServer.start();
                jettyServer.dump(System.err);
                jettyServer.join();
            } catch (Throwable t) {
                t.printStackTrace(System.err);
            } finally {
                jettyServer.destroy();
            }
        }
    }
    

    That's it. This solution solved my problem. Maybe it can be useful for others.

    0 讨论(0)
提交回复
热议问题