Apache Mina 白名单实现方法
Mina自带了一个黑名单过滤器BlacklistFilter,可过滤黑名单列表中的网络连接。用来防止非法的客户端访问。但在某些应用场景里需要设定白名单,只接收某些指定IP的客户端发来的数据。这就需要实现白名单功能。
我们可以自己实现白名单过滤器,方法很简单只需仿照BlacklistFilter做些修改即可。
我自己写的WhiteFilter,代码如下:
/**
* Whitelist filter (based on Mina's Blacklist filter).
*/
public class WhitelistFilter extends IoFilterAdapter {
private final List<Subnet> whitelist = new CopyOnWriteArrayList<Subnet>();
private final static Logger LOGGER = LoggerFactory.getLogger(WhitelistFilter.class);
public void setWhitelist(InetAddress[] addresses) {
if (addresses == null) {
throw new NullPointerException("addresses");
}
whitelist.clear();
for (InetAddress addr : addresses) {
allow(addr);
}
}
public void setSubnetWhitelist(Subnet[] subnets) {
if (subnets == null) {
throw new NullPointerException("Subnets must not be null");
}
whitelist.clear();
for (Subnet subnet : subnets) {
allow(subnet);
}
}
public void setWhitelist(Iterable<InetAddress> addresses) {
if (addresses == null) {
throw new NullPointerException("addresses");
}
whitelist.clear();
for (InetAddress address : addresses) {
allow(address);
}
}
public void setSubnetWhitelist(Iterable<Subnet> subnets) {
if (subnets == null) {
throw new NullPointerException("Subnets must not be null");
}
whitelist.clear();
for (Subnet subnet : subnets) {
allow(subnet);
}
}
public void allow(InetAddress address) {
if (address == null) {
throw new NullPointerException("Adress to block can not be null");
}
allow(new Subnet(address, 32));
}
public void allow(Subnet subnet) {
if (subnet == null) {
throw new NullPointerException("Subnet can not be null");
}
whitelist.add(subnet);
}
public void disallow(InetAddress address) {
if (address == null) {
throw new NullPointerException("Adress to unblock can not be null");
}
disallow(new Subnet(address, 32));
}
public void disallow(Subnet subnet) {
if (subnet == null) {
throw new NullPointerException("Subnet can not be null");
}
whitelist.remove(subnet);
}
@Override
public void sessionCreated(NextFilter nextFilter, IoSession session) {
if (isAllowed(session)) {
nextFilter.sessionCreated(session);
} else {
blockSession(session);
}
}
@Override
public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
if (isAllowed(session)) {
nextFilter.sessionOpened(session);
} else {
blockSession(session);
}
}
@Override
public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
if (isAllowed(session)) {
nextFilter.sessionClosed(session);
} else {
blockSession(session);
}
}
@Override
public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception {
if (isAllowed(session)) {
nextFilter.sessionIdle(session, status);
} else {
blockSession(session);
}
}
@Override
public void messageReceived(NextFilter nextFilter, IoSession session, Object message) {
if (isAllowed(session)) {
nextFilter.messageReceived(session, message);
} else {
blockSession(session);
}
}
@Override
public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
if (isAllowed(session)) {
nextFilter.messageSent(session, writeRequest);
} else {
blockSession(session);
}
}
private void blockSession(IoSession session) {
LOGGER.warn("Remote address is not allowed; closing.");
session.close(true);
}
private boolean isAllowed(IoSession session) {
SocketAddress remoteAddress = session.getRemoteAddress();
if (remoteAddress instanceof InetSocketAddress) {
InetAddress address = ((InetSocketAddress) remoteAddress).getAddress();
// check all subnets
for (Subnet subnet : whitelist) {
if (subnet.inSubnet(address)) {
return true;
}
}
}
return false;
}
}
调用时要加入whitelist过滤器
IoAcceptor acceptor = new NioSocketAcceptor();
WhitelistFilter whitelistFilter=new WhitelistFilter();
InetAddress[] address= new InetAddress;
address=InetAddress.getByName("192.168.136.123");
whitelistFilter.setWhitelist(address);
acceptor.getFilterChain().addFirst("white",whitelistFilter);
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("GBK"))));
acceptor.setHandler(new ServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
acceptor.bind(new InetSocketAddress(PORT));
这样服务端只会从指定的IP接收数据,如果客户端使用其他的IP地址则服务端拒绝连接。
页:
[1]