【问题标题】:Jetty - how to only allow requests from a specific domain码头 - 如何只允许来自特定域的请求
【发布时间】:2014-01-06 19:04:55
【问题描述】:

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

实现此安全功能的最佳方式是什么?

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

谢谢!

【问题讨论】:

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


    【解决方案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);
        }
    }
    

    【讨论】:

    • 有趣——虽然不是将 ip 地址列入黑名单——我希望我的 api 可用于仅通过我的前端应用程序访问我的网站的任何客户端。因此,如果客户端尝试直接从浏览器访问我的 api - 我想阻止该请求。
    • 啊,您在问题中说“来自某个域”,因此假设这是基于 IP 的限制。
    • 啊对不起-我的错。我的意思是请求是从某个域加载的前端应用发出的——因此我提到了跨域过滤器。
    • @JoakimErdfelt 我会把这个文件放在哪里?
    【解决方案2】:

    IPAccessHandler 类已弃用。推荐使用 InetAccessHandler。

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

    【讨论】:

    • 在那里你实例化你的处理程序。例如在 Jetty Server 的 init() 方法中。
    猜你喜欢
    • 1970-01-01
    • 2020-10-18
    • 2021-12-25
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 2018-02-01
    • 1970-01-01
    相关资源
    最近更新 更多