Java Spring MVC - 仅允许来自本地主机的请求到特定控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23238876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC - allowing requests from localhost only to specific controller
提问by Urbanleg
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')" />
采纳答案by Kre?imir Nesek
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()
localhost获取的远程 IP 地址是否确实是本地主机。
If you're using spring security then, as NimChimpsky suggested, it might be better plug in remote ip check into that. You could define a custom permission evaluator that checks remote ip address.
如果您正在使用 spring 安全性,那么正如 NimChimpsky 建议的那样,最好将远程 ip 检查插入其中。您可以定义一个自定义权限评估器来检查远程 IP 地址。
You could also use servlet filter and do the localhost check there for a specific URL (e.g. /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 的答案可能是最好的方法。
回答by NimChimpsky
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 安全性。
回答by Eric Wang
Here is a possible solution:
这是一个可能的解决方案:
steps:
脚步:
- write a listener, get the server side hostname or ip at startup time, and store it somewhere,
- add ServletRequest as a param of the method
- inside the method get the client hostname by:
ServletRequest.getServerName(...)
- compare client & server's ip or host,
- if local, then handle it,
- if not local, then ignore it, optionally give some tip,
- 编写一个监听器,在启动时获取服务器端主机名或ip,并将其存储在某处,
- 添加 ServletRequest 作为方法的参数
- 在方法内部通过以下方式获取客户端主机名:
ServletRequest.getServerName(...)
- 比较客户端和服务器的 ip 或主机,
- 如果是本地的,则处理它,
- 如果不是本地的,则忽略它,可选择提供一些提示,
回答by ezer
spring-security provides @PreAuthorize annotation that can be used on type or method so an alternative to <intercept-url>
can be @PreAuthorize("hasIpAddress('127.0.0.1')")
弹簧安全提供了可以在类型或方法中使用这样一种替代@PreAuthorize注释<intercept-url>
可以是@PreAuthorize("hasIpAddress('127.0.0.1')")
回答by mbaranauskas
@PreAuthorize("#request.getRemoteAddr().equals(#request.getLocalAddr())")