10

Is there any way to obtain STOMP client IP address? I am intercepting inbound channel but I cannot see any way to check the ip address.

Any help appreciated.

Damian
  • 593
  • 6
  • 27

3 Answers3

18

You could set the client IP as a WebSocket session attribute during the handshake with a HandshakeInterceptor:

public class IpHandshakeInterceptor implements HandshakeInterceptor {

    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
            WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {

        // Set ip attribute to WebSocket session
        attributes.put("ip", request.getRemoteAddress());

        return true;
    }

    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
            WebSocketHandler wsHandler, Exception exception) {          
    }
}

Configure your endpoint with the handshake interceptor:

@Override
protected void configureStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/ws").addInterceptors(new IpHandshakeInterceptor()).withSockJS();
}

And get the attribute in your handler method with a header accessor:

@MessageMapping("/destination")
public void handlerMethod(SimpMessageHeaderAccessor ha) {
    String ip = (String) ha.getSessionAttributes().get("ip");
    ...
}
Sergi Almar
  • 8,054
  • 3
  • 32
  • 30
  • 1
    It is possible to get this attribute in service without passing SimpMessageHeaderAccessor ? I mean something similiar to injecting HttpServletRequest – shark Nov 23 '15 at 15:02
  • 1
    Always getting ip as 127.0.0.1.How to get remote client's ip? – shabinjo Aug 31 '17 at 12:32
  • It is genius! :) And thank you for the deep answer with details of integration. I appreciate it. – Pasha Feb 08 '21 at 07:37
7

Below example updated to get the exact remote client ip:

@Component
public class IpHandshakeInterceptor implements HandshakeInterceptor {

   @Override
   public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                               WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
    // Set ip attribute to WebSocket session
    if (request instanceof ServletServerHttpRequest) {
        ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
        String ipAddress = servletRequest.getServletRequest().getHeader("X-FORWARDED-FOR");
        if (ipAddress == null) {
            ipAddress = servletRequest.getServletRequest().getRemoteAddr();
        }
        attributes.put("ip", ipAddress);
    }
    return true;
}

   public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                           WebSocketHandler wsHandler, Exception exception) {
}
}
shabinjo
  • 1,473
  • 1
  • 16
  • 22
  • It looks like your application is behind the reverse proxy and that is why you have to get the "X-FORWARDED-FOR" header. More information here: https://en.wikipedia.org/wiki/X-Forwarded-For So it feels like your statement "Below example updated to get the exact remote client ip" is actually for NOT TYPICAL situation as you have assumed when you wrote your answer, but for more specific situation. – Pasha Feb 08 '21 at 08:24
0

Tried to add this information as a comment, but stackoverflow complains that it is too long for the comment, so I post it as answer to

It is possible to get this attribute in service without passing SimpMessageHeaderAccessor ? I mean something similiar to injecting HttpServletRequest – shark Nov 23 '15 at 15:02

question.

I was able to achieve "close" results with such syntax:

@MessageMapping("/destination")
@SendTo("/topic/someTopic")
public String send(@Header("simpSessionAttributes") Map<String, Object> sessionAttributes) {
    String clientsAddress = sessionAttributes.get("ip"));
    return "The sender's address is: " + clientsAddress ;
}

I am not familiar to the origin of the "simpSessionAttributes" name of the header of the message, but I noticed that if I put the information in a way it is described in this thread by the @Sergi Almar - I get such result. But perhaps this name "simpSessionAttributes" may depend on some environment configuration or particular implementation of the message framework idk...

Also I do not mind to include this detalization as a part of the answer of the @Sergi Almar.

Pasha
  • 642
  • 6
  • 22