基于Spring Integration的TCP消息服务器如何实现地址白名单?
实现Spring Integration TCP地址白名单的方案
好问题!其实Spring Integration完全支持在TCP连接建立阶段实现地址白名单控制,只是这部分功能需要通过定制扩展来实现,文档里没有特别突出这个点。下面给你两种实用的实现方式:
方式一:自定义TcpConnectionInterceptor拦截连接
TcpConnectionInterceptor是Spring Integration提供的TCP连接生命周期拦截扩展点,我们可以利用它在连接建立后立即校验远程地址,不符合白名单就直接关闭连接。
- 实现拦截器(继承
TcpConnectionInterceptorSupport更简便):
import org.springframework.integration.ip.tcp.connection.TcpConnection; import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorSupport; import java.util.Set; public class WhitelistTcpInterceptor extends TcpConnectionInterceptorSupport { private final Set<String> allowedAddresses; public WhitelistTcpInterceptor(Set<String> allowedAddresses) { this.allowedAddresses = allowedAddresses; } @Override public void postConnect(TcpConnection connection) { // 解析远程IP地址,去掉端口和前缀 String remoteAddress = connection.getRemoteAddress().toString(); String remoteIp = remoteAddress.split(":")[0].replace("/", ""); if (!allowedAddresses.contains(remoteIp)) { System.out.println("拒绝来自非白名单地址的连接: " + remoteIp); try { connection.close(); } catch (Exception e) { e.printStackTrace(); } } super.postConnect(connection); } }
- 将拦截器配置到你的
TcpNetServerConnectionFactory:
@Bean public TcpNetServerConnectionFactory tcpServerFactory() { TcpNetServerConnectionFactory factory = new TcpNetServerConnectionFactory(1234); // 替换为你的服务端口 // 定义你的IP白名单 Set<String> whitelist = Set.of("192.168.1.100", "127.0.0.1"); WhitelistTcpInterceptor interceptor = new WhitelistTcpInterceptor(whitelist); factory.setConnectionInterceptorFactoryChain(interceptor); return factory; }
方式二:扩展TcpNetServerConnectionFactory重写连接接受逻辑
如果想在连接被正式接受之前就过滤(更早的阶段,减少资源消耗),可以直接扩展TcpNetServerConnectionFactory,重写连接接受的核心方法:
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.Set; public class WhitelistTcpServerFactory extends TcpNetServerConnectionFactory { private final Set<String> allowedAddresses; public WhitelistTcpServerFactory(int port, Set<String> allowedAddresses) { super(port); this.allowedAddresses = allowedAddresses; } @Override protected Socket doAccept(ServerSocket serverSocket) throws Exception { Socket socket = serverSocket.accept(); InetSocketAddress remoteAddr = (InetSocketAddress) socket.getRemoteSocketAddress(); String remoteIp = remoteAddr.getAddress().getHostAddress(); if (!allowedAddresses.contains(remoteIp)) { System.out.println("拒绝非白名单连接: " + remoteIp); socket.close(); return null; // 返回null会让工厂直接忽略这个连接 } return super.doAccept(serverSocket); } }
然后配置这个自定义工厂:
@Bean public TcpNetServerConnectionFactory tcpServerFactory() { Set<String> whitelist = Set.of("192.168.1.100", "127.0.0.1"); return new WhitelistTcpServerFactory(1234, whitelist); }
额外提示
- 如果需要支持子网掩码(比如
192.168.1.0/24),可以借助InetAddress相关工具类来实现IP范围校验 - 第二种方式的拦截时机更早,能避免后续不必要的资源初始化,适合性能敏感的场景
内容的提问来源于stack exchange,提问作者wrapperapps
相关产品推荐
相关产品推荐

