Karan
Karan

Reputation: 15104

Jetty - how to only allow requests from a specific domain

I have exposed an api provided by a jetty server to a front-end application. I want to make sure that only the front-end application (from a certain domain) has access to that api - any other requests should be unauthorised.

What's the best best way of implementing this security feature?

Update: I have set up a CrossOriginFilter - however, I can still access the api via basic GET request from my browser.

Thanks!

Upvotes: 2

Views: 3888

Answers (2)

Horcrux7
Horcrux7

Reputation: 24457

The class IPAccessHandler is deprecated. The InetAccessHandler is recommended.

org.eclipse.jetty.server.Server server = ...;
InetAccessHandler ipaccess = new InetAccessHandler();
ipaccess.include(clientIP);
ipaccess.setHandler(server.getHandler());
server.setHandler(ipaccess);

Upvotes: 2

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49515

Use the IPAccessHandler to setup whitelists and blacklists.

Example: this will allow 127.0.0.* and 192.168.1.* to access everything. But 192.168.1.132 cannot access /home/* content.

package jetty.demo;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.IPAccessHandler;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class IpAccessExample
{
    public static void main(String[] args)
    {
        System.setProperty("org.eclipse.jetty.servlet.LEVEL","DEBUG");
        System.setProperty("org.eclipse.jetty.server.handler.LEVEL","DEBUG");

        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8080);
        server.addConnector(connector);

        // Setup IPAccessHandler
        IPAccessHandler ipaccess = new IPAccessHandler();
        ipaccess.addWhite("127.0.0.0-255|/*");
        ipaccess.addWhite("192.168.1.1-255|/*");
        ipaccess.addBlack("192.168.1.132|/home/*");
        server.setHandler(ipaccess);

        // Setup the basic application "context" for this application at "/"
        // This is also known as the handler tree (in jetty speak)
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        // make context a subordinate of ipaccess
        ipaccess.setHandler(context);

        // The filesystem paths we will map
        String homePath = System.getProperty("user.home");
        String pwdPath = System.getProperty("user.dir");

        // Fist, add special pathspec of "/home/" content mapped to the homePath
        ServletHolder holderHome = new ServletHolder("static-home", DefaultServlet.class);
        holderHome.setInitParameter("resourceBase",homePath);
        holderHome.setInitParameter("dirAllowed","true");
        holderHome.setInitParameter("pathInfoOnly","true");
        context.addServlet(holderHome,"/home/*");

        // Lastly, the default servlet for root content
        // It is important that this is last.
        ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
        holderPwd.setInitParameter("resourceBase",pwdPath);
        holderPwd.setInitParameter("dirAllowed","true");
        context.addServlet(holderPwd,"/");

        try
        {
            server.start();
            server.join();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }
}

Or alternatively, write your own Handler to filter based on some other arbitrary rule.

Such as looking for a required request header, something that your specific front-end application provides, but a browser would not.

package jetty.demo;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;

public class BanBrowserHandler extends HandlerWrapper
{
    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        String xfe = request.getHeader("X-FrontEnd");
        if ((xfe == null) || (!xfe.startsWith("MagicApp-")))
        {
            // not your front-end
            response.sendError(HttpStatus.FORBIDDEN_403);
            baseRequest.setHandled(true);
            return;
        }

        getHandler().handle(target,baseRequest,request,response);
    }
}

Upvotes: 1

Related Questions