本文会给大家讲解springcloud集成eureka及整合spring security相关配置。以及在整合过程中会出现的异常情况。

SpringCloud整合eureka

eureka服务中心项目添加pom依赖文件:

<dependencies>
   <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--安全认证-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>${spring-boot.version}</version>
    </dependency>
</dependencies>

其中security为安全相关组件,也就是spring security。而spring-cloud-starter-netflix-eureka-server为spring cloud集成eureka相关依赖。

application.yml相关配置

server:
  port: 8761
spring:
  profiles: eureka-colony1
eureka:
  instance:
    hostname: eureka-colony1
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://admin:admin@192.168.1.108:8762/eureka/
  server:
    # 关闭自我保护
    enable-self-preservation: false
    # 清理服务器
    eviction-interval-timer-in-ms: 60000

上述配置为eureka相关配置,其中defaultZone为链接另外一个eureka地址信息,前面的admin:admin@为指定访问的security所需的账户密码。相关的密码配置项如下:

security:
  user:
    name: admin
    password: admin

集群部署时,另外一台部署情况与上述配置一致,只需修改hostname名称和defaultZone地址即可。

启动类添加注解:

@SpringBootApplication
@EnableEurekaServer
public class TmsEurekaApplication {
   public static void main(String[] args) {
      SpringApplication.run(TmsEurekaApplication.class, args);
   }
}

启动类需要添加@EnableEurekaServer注解,用来启动eureka服务。

客户端配置

服务提供者与服务客户端要修改application.yml,修改注册链接,带上用户名密码:

# eureka注册中心使用用户名密码,所以这里要带上用户名密码向eureka注册
defaultZone: http://admin:admin@192.168.1.108:8761/eureka/, http://admin:admin@192.168.1.108:8762/eureka/

启动服务之后,访问http://192.168.1.108:8761,则会弹出如下登录框:

springcloud-eureka集群及整合spring-security插图

输入上面配置的用户名和密码配置即可。

启动2个服务提供者,已在eureka注册中心注册:

springcloud-eureka集群及整合spring-security插图1

异常情况

不同版本的spring cloud和spring security,如果按照上述步骤来操作客户端连接eureka服务时,很可能会遇到下面的异常:

2019-01-06 21:31:46.147  WARN 3456 --- [nfoReplicator-0] c.n.d.s.t.d.RetryableEurekaHttpClient    : Request execution failure with status code 401; retrying on another server if available
2019-01-06 21:31:46.160  WARN 3456 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_UNKNOWN/192.168.0.104:8090 - registration failed Cannot execute request on any known server

com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
	at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.3.jar:1.9.3]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.3.jar:1.9.3]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) ~[eureka-client-1.9.3.jar:1.9.3]
	at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.9.3.jar:1.9.3]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.3.jar:1.9.3]
	at com.netflix.discovery.DiscoveryClient.register(DiscoveryClient.java:829) ~[eureka-client-1.9.3.jar:1.9.3]
	at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:121) [eureka-client-1.9.3.jar:1.9.3]
	at com.netflix.discovery.InstanceInfoReplicator$1.run(InstanceInfoReplicator.java:101) [eureka-client-1.9.3.jar:1.9.3]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_181]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_181]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_181]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_181]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]

这是因为springboot引入spring-boot-starter-security做安全校验后,自动开启CSRF安全认证,任何一次服务请求默认都需要CSRF 的token(自行补脑Spring的CSRF验证),而Eureka-client不会生成该token,故启动时会报如上错误。

解决方案:关闭csrf 验证,或者说关闭针对eureka路径的csrf验证。

在springboot项目中添加对应配置项目:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().ignoringAntMatchers("/eureka/**");
        super.configure(http);
    }
}

这里仅忽略掉了/eureka请求路径的csrf验证。虽然也可以直接关闭csrf验证,但不推荐,具体操作如下:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        super.configure(http);
    }

如果查看官方文档,也是推荐第一种方式进行配置:

springcloud-eureka集群及整合spring-security插图2

对应链接地址:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/multi/multi_spring-cloud-eureka-server.html#_securing_the_eureka_server

完成上述配置,重启整个服务即可解决链接的问题。



springcloud-eureka集群及整合spring-security插图3

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:https://choupangxia.com/2021/01/20/springcloud-eureka/