Jetty - 如何仅允许来自特定域的请求

时间:2013-12-18 14:32:57

标签: api request cross-domain jetty embedded-jetty

我已将jetty服务器提供的api暴露给前端应用程序。我想确保只有前端应用程序(来自某个域)才能访问该API - 任何其他请求都应该是未经授权的。

实施此安全功能的最佳方法是什么?

更新:我已经设置了CrossOriginFilter - 但是,我仍然可以通过浏览器的基本GET请求访问api。

谢谢!

2 个答案:

答案 0 :(得分:1)

使用IPAccessHandler设置白名单和黑名单。

示例:这将允许127.0.0.*192.168.1.*访问所有内容。 但192.168.1.132无法访问/home/*内容。

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);
        }
    }
}

或者,编写您自己的处理程序以根据其他任意规则进行过滤。

例如查找所需的请求标头,这是您的特定前端应用程序提供的内容,但浏览器不会。

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);
    }
}

答案 1 :(得分:1)

不推荐使用类IPAccessHandler。建议使用InetAccessHandler。

InetAccessHandler ipaccess = new InetAccessHandler();
ipaccess.include(clientIP);
ipaccess.setHandler(server.getHandler());
server.setHandler(ipaccess);