Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧靴+;尤里卡+;SSL环境中的CloudConfig_Java_Spring_Spring Boot_Tomcat_Ssl - Fatal编程技术网

Java 弹簧靴+;尤里卡+;SSL环境中的CloudConfig

Java 弹簧靴+;尤里卡+;SSL环境中的CloudConfig,java,spring,spring-boot,tomcat,ssl,Java,Spring,Spring Boot,Tomcat,Ssl,我需要以下microservice环境的加密设置。一个支持SSL的Eureka服务器,具有云配置服务和多个微服务,只需连接到发现服务、读取配置并运行其内容。一切都通过HTTPS和身份验证 所以…我所做的: 在/config上包含云配置服务的Eureka Discovery服务器/* 服务器正在向Eureka服务器注册,Eureka仪表板将显示该实例。此服务在启用SSL和用户身份验证的端口9001上运行。服务照常进行 然后我创建了一个新的SpringBoot服务,它连接到Eureka并注册到它。由

我需要以下microservice环境的加密设置。一个支持SSL的Eureka服务器,具有云配置服务和多个微服务,只需连接到发现服务、读取配置并运行其内容。一切都通过HTTPS和身份验证

所以…我所做的:

在/config上包含云配置服务的Eureka Discovery服务器/* 服务器正在向Eureka服务器注册,Eureka仪表板将显示该实例。此服务在启用SSL和用户身份验证的端口9001上运行。服务照常进行

然后我创建了一个新的SpringBoot服务,它连接到Eureka并注册到它。由于自签名证书,我在本文中编写了一个小的SSLConfiguration类:将我的个人信任库提供给底层的EurekaClient。 我们的所有服务都配置了application.yml:

spring:
    application:
        name: mark2

server:
    port: 9998
    ssl:
        enabled: true
        key-store: classpath:keystore.p12
        key-store-password: changeit
        key-store-type: PKCS12
        keyAlias: mark2

http:
    client:
      ssl:
          trust-store: classpath:keystore.p12
          trust-store-password: changeit

eureka:
    client:
        serviceUrl:
            defaultZone: https://user:pass@localhost:9001/eureka
客户端可以完美地连接和注册

现在我希望SpringBoot服务注册到Eureka服务器,并在引导过程中从配置服务器加载配置。因此,我将spring、http和eureka设置移到bootstrap.yml

spring:
    application:
        name: mark2
    cloud:
        config:
            username: user
            password: password
            discovery:
                enabled: true
                serviceId: EUREKA-DISCOVERY-SERVICE
            failFast: true
            name: my
            profile: settings
#            label: v1

http:
    client:
      ssl:
          trust-store: classpath:keystore.p12
          trust-store-password: changeit

eureka:
    client:
        serviceUrl:
            defaultZone: https://user:password@localhost:9001/eureka
    instance:
        metadataMap:
            user: user
            password: password
            configPath: /config
如果服务启动,它将在引导过程中尝试连接到Eureka服务器。这不起作用,因为它不信任来自Eureka服务器的自签名证书。我不能使用@Configure或@Bean,因为我在引导中(至少我发现没有任何东西起作用)。上述SSLConfiguration解决方案也不起作用

好的,然后我用javax.net.ssl.trustStore等将JVM参数设置为我的个人信任库

bootRun {
   jvmArgs = [ 
     "-Djavax.net.ssl.trustStore=/absolute/path/to/keystore.p12", 
     "-Djavax.net.ssl.trustStorePassword=changeit", 
     "-Djavax.net.ssl.trustStoreType=PKCS12", 
   ]
}
服务启动,Eureka客户端开始与Eureka服务器通信,找到云配置实例并加载属性文件,然后创建Spring上下文。该属性仅包含一些测试属性

但是,错误是:

Field optionalArgs in org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration required a single bean, but 2 were found:
    - getTrustStoredEurekaClient: defined by method 'getTrustStoredEurekaClient' in class path resource [de/mark2/SslConfiguration.class]
    - discoveryClientOptionalArgs: defined by method 'discoveryClientOptionalArgs' in org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration
好的,坏的,但是好的。因为我们提供了JVM参数,所以不应该再使用SSLConfiguration。删除

现在-一切似乎都正常,服务应该启动嵌入式Tomcat。但这不起作用,因为另一个异常是,配置的密钥库为空(“trustAnchors参数必须为非空”表示密钥库存在,但不包含任何别名证书)。我认为,JVM参数用于嵌入式Tomcat中,它试图使用信任库来获取某种ClientCertificates之类的证书。我不知道

如果我禁用云配置,嵌入式Tomcat仍然会有相同的错误。如果我也删除了JVM参数,服务就会出现


所以-我不知道,我需要做什么,在引导过程中进行加密通信,而不为Eureka客户机定义JVM参数,或者给嵌入式tomcat一个信任库(他不需要)

有趣的事情-如果我使用嵌入式Undertow而不是嵌入式Tomcat,它会工作-但这就是解决方案吗

dependencies {
  compile("org.springframework.boot:spring-boot-starter") {
    exclude module: "tomcat-embed-el"
  }
  compile("org.springframework.boot:spring-boot-starter-web") {
    exclude module: "spring-boot-starter-tomcat"
  }
  compile('org.springframework.boot:spring-boot-starter-undertow')
  ...
}

定义META-INF/spring.factories并添加org.springframework.cloud.bootstrap.bootstrap配置=。。。线

课程可以是:

@Configuration
@BootstrapConfiguration
public class SslConfiguration {
  @Value("${http.client.ssl.trust-store}")
  private URL trustStore;
  @Value("${http.client.ssl.trust-store-password}")
  private String trustStorePassword;

  @Bean
  public DiscoveryClient.DiscoveryClientOptionalArgs getTrustStoredEurekaClient(SSLContext sslContext) {
    DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs();
    args.setSSLContext(sslContext);
    return args;
  }

  @Bean
  public SSLContext sslContext() throws Exception {
    return new SSLContextBuilder().loadTrustMaterial(trustStore, trustStorePassword.toCharArray()).build();
  }
}
由于DiscoveryClientOptionalArgs现在定义了两次,因此添加另一个类,该类在Spring上下文启动后加载

@Configuration
public class DiscoveryServiceConfiguration {
  @Bean
  public static BeanFactoryPostProcessor registerPostProcessor() {
    return (ConfigurableListableBeanFactory beanFactory) -> {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      for (String beanDefinitionName : registry.getBeanDefinitionNames()) {
        if (beanDefinitionName.equalsIgnoreCase("discoveryClientOptionalArgs")) {
          BeanDefinition beanDefinition = registry.containsBeanDefinition(beanDefinitionName) ? registry.getBeanDefinition(beanDefinitionName) : null;
          if (beanDefinition != null) {
            if (registry.containsBeanDefinition(beanDefinitionName)) {
              registry.removeBeanDefinition(beanDefinitionName);
            }
          }
        }
      }
    };
  }
}
那也行。您不再需要定义JVM参数