spring cloud eureka 限制ip和实例名称注册

为了保护我们eureka注册中的安全我们需要限制ip和实例名称注册,eureka官方没有提供相关的配置,于是我们只能去扩展它的源码
1.创建一个CustomInstanceRegister 代码如下:


import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.Application;
import com.netflix.eureka.EurekaServerConfig;
import com.netflix.eureka.lease.Lease;
import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl;
import com.netflix.eureka.resources.ServerCodecs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class CustomInstanceRegister extends PeerAwareInstanceRegistryImpl implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    private int defaultOpenForTrafficCount;

    private List<String> allowedRegisteredIpAddress = new ArrayList<>();

    private List<String> allowedRegisteredInstanceNames = new ArrayList<>();

    public CustomInstanceRegister(EurekaServerConfig serverConfig, EurekaClientConfig clientConfig,
                                  ServerCodecs serverCodecs, EurekaClient eurekaClient, int expectedNumberOfRenewsPerMin,
                                  int defaultOpenForTrafficCount, List<String> allowedRegisteredIpAddress,
                                  List<String> allowedRegisteredInstanceNames) {
        super(serverConfig, clientConfig, serverCodecs, eurekaClient);
        this.expectedNumberOfClientsSendingRenews = expectedNumberOfRenewsPerMin;
        this.defaultOpenForTrafficCount = defaultOpenForTrafficCount;
        this.allowedRegisteredIpAddress = allowedRegisteredIpAddress;
        this.allowedRegisteredInstanceNames = allowedRegisteredInstanceNames;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public boolean cancel(String appName, String id, boolean isReplication) {
        log.debug("注销的appName:{}, id:{}, isReplication{}", appName, id, isReplication);
        pushEvent(new EurekaInstanceCanceledEvent(this, appName, id, isReplication));
        return super.cancel(appName, id, isReplication);
    }

    @Override
    public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
        super.openForTraffic(applicationInfoManager, count == 0 ? defaultOpenForTrafficCount : count);
    }



    @Override
    public void register(InstanceInfo info, boolean isReplication) {
        log.debug("注册地址:{}", info.getIPAddr());
        printLogo(info);
        pushEvent(new EurekaInstanceRegisteredEvent(this, info, resolveInstanceDuration(info),
                isReplication));
        String ip = info.getIPAddr();
        if (!this.allowedRegisteredIpAddress.contains(ip)) {
            log.debug("ip为【{}】的实例不允许注册", ip);
            return;
        }

        if (!this.allowedRegisteredInstanceNames.contains(info.getAppName())) {
            log.debug("实例名称为【{}】的实例不允许注册", info.getAppName());
            return;
        }

        super.register(info, isReplication);
    }

    @Override
    public void register(InstanceInfo info, int leaseDuration, boolean isReplication) {
        log.debug("注册地址:{}", info.getIPAddr());
        printLogo(info);
        pushEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication));
        String ip = info.getIPAddr();
        if (!this.allowedRegisteredIpAddress.contains(ip)) {
            log.debug("ip为【{}】的实例不允许注册", ip);
            return;
        }

        if (!this.allowedRegisteredInstanceNames.contains(info.getAppName())) {
            log.debug("实例名称为【{}】的实例不允许注册", info.getAppName());
            return;
        }

        super.register(info, isReplication);
    }

    private void printLogo(InstanceInfo instanceInfo) {
        log.debug("实例名称为:{},地址为:{}注册到注册中心", instanceInfo.getAppName(), instanceInfo.getIPAddr());
    }

    @Override
    public boolean renew(String appName, String id, boolean isReplication) {
        log.debug("appName:{},instanceId:{}", appName, id);
        // 获取所有可以的相关服务实例
        List<Application> applications = getSortedApplications();
        applications.forEach(application -> {
            if (application.getName().equals(appName)) {
                InstanceInfo instanceInfo = null;
                for (InstanceInfo info : application.getInstances()) {
                    if (info.getId().equals(id)) {
                        instanceInfo = info;
                        break;
                    }
                }

                // 发布重置事件
                pushEvent(new EurekaInstanceRenewedEvent(this, appName,  id,  instanceInfo, isReplication));
            }
        });

      return super.renew(appName, id, isReplication);

    }

    /**
     * 唤醒事件
     * @param event
     */
    public void pushEvent(ApplicationEvent event) {
        this.applicationContext.publishEvent(event);
    }

    private int resolveInstanceDuration(InstanceInfo info) {
        int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
        if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
            leaseDuration = info.getLeaseInfo().getDurationInSecs();
        }

        return leaseDuration;
    }
}

  1. 重写配置文件覆盖原本的InstanceRegistry
@Configuration
@EnableConfigurationProperties(CustomEurekaProperty.class)
public class CustomEurekaConfig {
    @Autowired
    private EurekaServerConfig eurekaServerConfig;

    @Autowired
    private EurekaClientConfig eurekaClientConfig;

    @Autowired
    @Qualifier(value = "eurekaClient")
    private EurekaClient eurekaClient;

    @Autowired
    private CustomEurekaProperty property;

    @Primary
    @Bean(name = "customAwareInstanceRegistry")
    public PeerAwareInstanceRegistry peerAwareInstanceRegistry(
            ServerCodecs serverCodecs) {
        this.eurekaClient.getApplications();
        List<String> ips = new ArrayList<>();
        String[] allowIps = StringUtils.split(property.getAllowIpAddr(), ",");
        if (allowIps.length > 0) {
            for (String ip : allowIps) {
                ips.add(StringUtils.trim(ip));
            }
        }

        List<String> instanceNames = new ArrayList<>();
        String[] names = StringUtils.split(property.getAllowInstanceNames(), ",");
        if (names.length > 0) {
            for (String name : names) {
                instanceNames.add(StringUtils.trim(name).toUpperCase());
            }
        }

        return new CustomInstanceRegister(
                this.eurekaServerConfig,
                this.eurekaClientConfig,
                serverCodecs,
                this.eurekaClient,
                this.property.getExpectedNumberOfRenewsPerMin(),
                this.property.getDefaultOpenForTrafficCount(),
                ips, instanceNames);
    }

}

  1. 定义配置类
@Setter
@Getter
@ConfigurationProperties(prefix = "communal.eureka")
public class CustomEurekaProperty {

    private String allowIpAddr = "127.0.0.1";

    private int defaultOpenForTrafficCount = 1;

    private int expectedNumberOfRenewsPerMin = 1;

    private String allowInstanceNames = "flow-app-provider";
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值