简体   繁体   English

Spring MVC - 仅允许来自本地主机的请求到特定控制器

[英]Spring MVC - allowing requests from localhost only to specific controller

I have a specific controller (among many other controllers).我有一个特定的控制器(在许多其他控制器中)。 I would like to allow requests to this controller that are being invoked from localhost only.我想允许仅从本地主机调用的对这个控制器的请求。 Whats the best way to do this?什么是最好的方法来做到这一点?

here is the controller:这是控制器:

@Controller
public class LocalProvider {

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
@ResponseBody
public responseDTO doSomethingForLocalRequest(@RequestBody ReqDTO reqDTO ) {

//do something
}

EDIT :编辑 :

Succesffuly achieved that by adding the following to spring security.xml:通过将以下内容添加到 spring security.xml 中,成功实现了这一目标:

<intercept-url pattern="/someURL/*" access="hasIpAddress('127.0.0.1')" />

I would create a custom annotation @LocalhostOnly and a MVC interceptor that would check if handler method is annotated with @LocalhostOnly and in that case check if remote ip address fetched from the HttpServletRequest.getRemoteAddr() is indeed localhost.我将创建一个自定义注释@LocalhostOnly和一个 MVC 拦截器,用于检查处理程序方法是否使用@LocalhostOnly注释,在这种情况下,检查从HttpServletRequest.getRemoteAddr()获取的远程 IP 地址是否确实是本地主机。

If you're using spring security then, as NimChimpsky suggested, it might be better plug in remote ip check into that.如果您正在使用 spring 安全性,那么正如 NimChimpsky 建议的那样,最好将远程 ip 检查插入其中。 You could define a custom permission evaluator that checks remote ip address.您可以定义一个自定义权限评估器来检查远程 IP 地址。

You could also use servlet filter and do the localhost check there for a specific URL (eg /someURL** ).您还可以使用 servlet 过滤器并在那里对特定 URL(例如/someURL** )进行本地主机检查。

Lastly, be aware that if you'll be running the application behind a reverse proxy at some point, all the requests will look like they arrived from localhost (that is, if reverse proxy is installed at the same host).最后,请注意,如果您将在某个时候在反向代理后面运行应用程序,则所有请求看起来都来自本地主机(即,如果反向代理安装在同一主机上)。 In that case you'll need to pick up the ip address from X-Forwarded-For header.在这种情况下,您需要从X-Forwarded-For标头中获取 IP 地址。

EDIT编辑

Spring security actually has ip checking expression hasIpAddress('127.0.0.1') so NimChimpsky's answer is probably the best way to go. Spring security 实际上有 ip 检查表达式hasIpAddress('127.0.0.1')所以 NimChimpsky 的答案可能是最好的方法。

spring-security 提供了可用于类型或方法的 @PreAuthorize 注释,因此<intercept-url>的替代方案可以是@PreAuthorize("hasIpAddress('127.0.0.1')")

To restrict access to your whole webserveryou could use要限制对整个网络服务器的访问,您可以使用

<Connector port="8080" address="127.0.0.1" maxHttpHeaderSize="8192"

In server xml of tomcat (or similar in a different app server).在 tomcat 的服务器 xml 中(或在不同的应用程序服务器中类似)。

For one app use add allow="localhost" to the context :对于一个应用程序,使用添加 allow="localhost" 到上下文:

<Context>
    <Valve className="org.apache.catalina.valves.RemoteHostValve" allow="localhost"/>
</Context>

But for specific controller methods, you'll be best using spring security.但是对于特定的控制器方法,最好使用 spring 安全性。

Solution is to use the following expression:解决方案是使用以下表达式:

@PreAuthorize("#request.getRemoteAddr().equals(#request.getLocalAddr())")

As first comment suggested, Failed to evaluate expression error will show using #request if @P("request") HttpServletRequest parameter is missing.正如第一条评论所建议的那样,如果缺少@P("request") HttpServletRequest参数,则使用#request将显示Failed to evaluate expression错误。

Full solution:完整解决方案:

@PreAuthorize("#request.getRemoteAddr().equals(#request.getLocalAddr())")
@PostMapping("/doSomething")
public void myMethod(@P("request") HttpServletRequest request) {
    ...
}

Here is a possible solution: 这是一个可能的解决方案:

steps: 脚步:

  • write a listener, get the server side hostname or ip at startup time, and store it somewhere, 编写一个监听器,在启动时获取服务器端主机名或ip,并将其存储在某处,
  • add ServletRequest as a param of the method 添加ServletRequest作为方法的参数
  • inside the method get the client hostname by: ServletRequest.getServerName(...) 在方法内部获取客户端主机名: ServletRequest.getServerName(...)
  • compare client & server's ip or host, 比较客户端和服务器的ip或主机,
  • if local, then handle it, 如果是本地的,那么处理它,
  • if not local, then ignore it, optionally give some tip, 如果不是本地的,那么忽略它,可选择给出一些提示,

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

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