Spring Websockets STOMP - get client IP address

后端 未结 3 1999
孤街浪徒
孤街浪徒 2021-02-08 21:21

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.

相关标签:
3条回答
  • 2021-02-08 21:49

    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) {
    }
    }
    
    0 讨论(0)
  • 2021-02-08 21:52

    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.

    0 讨论(0)
  • 2021-02-08 22:08

    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");
        ...
    }
    
    0 讨论(0)
提交回复
热议问题