0


SpringCloud Zookeeper 配置用户名密码 源码分析

最近公司为了访问安全,给Zookeeper 设置了用户名密码,这样SpringCloud用Zookeeper 作为注册中心的服务就访问不了,网上搜了很多也没讲如何配置的,都是讲Zookeeper 如何设置密码的。按惯例是解决了,不然也不会心血来潮写个文章来记录下~!

一、SpringCloud注册中心配置

1、引用jar包

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zookeeper-discovery</artifactId></dependency>

2、在启动项配置开启注解

@SpringBootApplication@EnableDiscoveryClientpublicclassDemoApplication{publicstaticvoidmain(String[] args){SpringApplication.run(DemoApplication.class, args);}}

3、在application.yml配置参数

# 应用服务端口server.port:8080# 应用名称spring.application.name: demo-center
# spring-cloudspring.cloud:zookeeper.connect-string: 127.0.0.1:2181loadbalancer:ribbon.enabled:falsecache.enabled:false

二、源码分析

这样基于Zookeeper为注册中心就配置好了,如果Zookeeper需要用户密码访问再怎么配置,Spring Cloud Zookeeper官网文档介绍:在Zookeeper自动配置类初始化的时候通过CuratorFramework可以设置认证的用户名和密码,请参阅 Zookeeper 自动配置类

Zookeeper 在自动配置的时候生成一个CuratorFramework ,查看CuratorFramework 源码并没有提供addAuthInfo方法(官方文档也有出错的时候~)

@Bean(destroyMethod ="close")@ConditionalOnMissingBeanpublicCuratorFrameworkcuratorFramework(RetryPolicy retryPolicy,ZookeeperProperties properties,ObjectProvider<CuratorFrameworkCustomizer> optionalCuratorFrameworkCustomizerProvider,ObjectProvider<EnsembleProvider> optionalEnsembleProvider,ObjectProvider<TracerDriver> optionalTracerDriverProvider)throwsException{CuratorFrameworkFactory.Builder builder =CuratorFrameworkFactory.builder();EnsembleProvider ensembleProvider = optionalEnsembleProvider.getIfAvailable();if(ensembleProvider !=null){
            builder.ensembleProvider(ensembleProvider);}else{
            builder.connectString(properties.getConnectString());}
        builder.sessionTimeoutMs((int) properties.getSessionTimeout().toMillis()).connectionTimeoutMs((int) properties.getConnectionTimeout().toMillis()).retryPolicy(retryPolicy);

        optionalCuratorFrameworkCustomizerProvider.orderedStream().forEach(curatorFrameworkCustomizer -> curatorFrameworkCustomizer.customize(builder));CuratorFramework curator = builder.build();
        optionalTracerDriverProvider.ifAvailable(tracerDriver ->{if(curator.getZookeeperClient()!=null){
                curator.getZookeeperClient().setTracerDriver(tracerDriver);}});
        curator.start();if(log.isTraceEnabled()){
            log.trace("blocking until connected to zookeeper for "+ properties.getBlockUntilConnectedWait()+ properties.getBlockUntilConnectedUnit());}
        curator.blockUntilConnected(properties.getBlockUntilConnectedWait(), properties.getBlockUntilConnectedUnit());if(log.isTraceEnabled()){
            log.trace("connected to zookeeper");}return curator;}

但是通过自动配置代码可以看到CuratorFramework 是通过CuratorFrameworkFactory.Builder生成的,这种是spring常用代码写作技巧,查看源码Builder提供一个authorization和文档上说的一样可以添加用户名和密码。

CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder();
builder.authorization("digest","username :password").getBytes());

可以看到Builder 是方法内部变量,如何在方法外调用到Builder ,或者是直接重写Zookeeper 自动配置再加入authorization;看源码在builder.build()之前,builder对象还被optionalCuratorFrameworkCustomizerProvider调用

    optionalCuratorFrameworkCustomizerProvider.orderedStream().forEach(curatorFrameworkCustomizer -> 
                curatorFrameworkCustomizer.customize(builder));

optionalCuratorFrameworkCustomizerProvider是通过Sring容器注入进来的

publicCuratorFrameworkcuratorFramework(RetryPolicy retryPolicy,ZookeeperProperties properties,ObjectProvider<CuratorFrameworkCustomizer> optionalCuratorFrameworkCustomizerProvider,ObjectProvider<EnsembleProvider> optionalEnsembleProvider,ObjectProvider<TracerDriver> optionalTracerDriverProvider)throwsException{

由此可见

ObjectProvider<CuratorFrameworkCustomizer> 

是框架专门开放出来给用户添加个性化属性准备的

@FunctionalInterfacepublicinterfaceCuratorFrameworkCustomizer{voidcustomize(CuratorFrameworkFactory.Builder builder);}

三、配置ZK用户名密码

通过上面的源码解析,我们只要实现CuratorFrameworkCustomizer 注入到Spring容器中,Zookeeper 在自动配置的时候就可以调用到了,上代码:

@ConfigurationpublicclassZookeeperConfigurerimplementsCuratorFrameworkCustomizer{@Value("${spring.cloud.zookeeper.username:}")privateString username;@Value("${spring.cloud.zookeeper.password:}")privateString password;@Overridepublicvoidcustomize(CuratorFrameworkFactory.Builder builder){if(StrUtil.isNotBlank(username)&&StrUtil.isNotBlank(password)){
            builder.authorization("digest",(username +":"+ password).getBytes());}}}

这里调用配置文件,如果配置文件配置了用户名密码就配置,如果没有配置就略过,配置文件可以改为

# spring-cloudspring.cloud:zookeeper:connect-string: 127.0.0.1:2181username: username
    password: password
  loadbalancer:ribbon.enabled:falsecache.enabled:false

由此就顺利解决SpringCloud Zookeeper 配置用户名密码 的问题了。


本文转载自: https://blog.csdn.net/Return_Code/article/details/126750925
版权归原作者 Return_Code 所有, 如有侵权,请联系我们删除。

“SpringCloud Zookeeper 配置用户名密码 源码分析”的评论:

还没有评论