简体   繁体   中英

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:

<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.

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.

You could also use servlet filter and do the localhost check there for a specific URL (eg /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.

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 提供了可用于类型或方法的 @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).

For one app use add allow="localhost" to the context :

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

But for specific controller methods, you'll be best using spring security.

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.

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,
  • 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,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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