简体   繁体   English

限制J2EE servlet只能从localhost调用的正确方法是什么?

[英]What is the proper way to restrict a J2EE servlet to only be called from the localhost?

I am working on building a servlet to perform work that should only be able to be initiated from the host itself. 我正在构建一个servlet来执行只能从主机本身启动的工作。 My current plan is to check the request object in the service method: 我目前的计划是检查服务方法中的请求对象:

public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException

The only methods I see on ServletRequest that seem relevant are getRemoteHost() and getRemoteAddr() . 我在ServletRequest上看到的唯一ServletRequest方法是getRemoteHost()getRemoteAddr() My biggest concerns are whether this could be spoofed (someone could send an inbound request with the source IP 127.0.0.1 and start the process) or if checking the IP against 127.0.0.1 could fail if IPv6 is being used. 我最担心的是这是否可能被欺骗(有人可以使用源IP 127.0.0.1发送入站请求并启动进程),或者如果使用IPv6,则检查IP对127.0.0.1可能会失败。

There will be a credential which should prevent an IP spoof from being successful but I can't help but feel like there's a better, more direct way to check (or otherwise restrict) the source of the request. 将有一个凭证可以防止IP欺骗成功,但我不禁感到有更好,更直接的方式来检查(或以其他方式限制)请求的来源。

Is there a standard way to reliably make this restriction that is independent of IP version and safe from spoofing (assuming an attacker could get the credential but not access to the server)? 有没有一种标准方法可靠地使这种限制独立于IP版本并且不受欺骗(假设攻击者可以获取凭证但不能访问服务器)? I think from a security perspective the credential should be sufficient; 我认为从安全角度来看,凭证应该足够了; I'm mostly interested in what the 'right' way to solve this problem is. 我最感兴趣的是解决这个问题的“正确”方法是什么。

EDIT: 编辑:

I don't believe this is a duplicate of java- using a filter to check remote address as I was not considering using a filter in the first place. 我不相信这是java的重复 - 使用过滤器检查远程地址,因为我没有考虑首先使用过滤器。 While a filter-based solution was eventually what I went with this question is open to other potential solutions as well (for example, Raffaele's suggestion to use a server socket could prove useful to someone else or an answer that hasn't been posted yet could be superior to both methods). 虽然我最终采用基于过滤器的解决方案,但这个问题对其他可能的解决方案也是开放的(例如,Raffaele建议使用服务器套接字可能对其他人有用或者尚未发布的答案可能优于两种方法)。

You can use Filters : 您可以使用Filters

class OnlyLocalhostFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if (servletRequest.getLocalAddr().equals(servletRequest.getRemoteAddr())) {
            filterChain.doFilter(servletRequest, servletResponse);
        }

    }

    @Override
    public void destroy() {

    }
}

After that declare you filter OnlyLocalhostFilter in web.xml and bind it to servlet you want. 之后声明您在web.xml过滤OnlyLocalhostFilter并将其绑定到您想要的servlet。

UPDATE: 更新:

This solution not always works right. 此解决方案并不总是正常。 Found the answer here 这里找到答案

The standard way to solve this is not to act at the servlet (application) level, but instead bind your entire server socket on 127.0.0.1 (or another loopback address). 解决此问题的标准方法不是在servlet(应用程序)级别执行操作,而是在127.0.0.1 (或其他环回地址)上绑定整个服务器套接字。

I think the default API for Java server socket uses 0.0.0.0 which is anyaddress , but if you specify a loopback address like 127.0.0.1 (or localhost ) your application is protected at the kernel level. 我认为Java服务器套接字的默认API使用0.0.0.0 ,这是任何地址 ,但是如果指定一个环回地址,如127.0.0.1 (或localhost ),则应用程序在内核级别受到保护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM