代码信息
本篇文章涉及代码版本
组件 | 版本 |
---|---|
Spring Boot | 2.0.8.RELEASE |
Spring Cloud | Finchley.SR1 |
本篇文章涉及应用
应用 | 说明 |
---|---|
base-eureka-security | 服务发现-安全模式 |
base-producer-security | 服务提供方-安全模式 |
搭建安全模式下的服务发现中心
之前我们连接Eureka都是使用的默认配置,只需要知道服务中心的地址就可以将服务注册到服务中心中,假如不需要任何认证就可以注册到服务中心这样并不安全,所以我们可以为服务中心设置账号密码。
构建maven依赖
和之前普通版的依赖相比只需要增加security相关的依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
父类pom的配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--lombok工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
application.yml
配置上面除了security相关的配置之外不需要做任何改动。
spring:
application:
# 项目名称
name: base-eureka
# 安全配置
security:
user:
name: user
password: 123456
server:
port: 8004
eureka:
instance:
# 主机名称
hostname: localhost
client:
# 是否要注册到其他Server上
register-with-eureka: false
# 是否需要拉取服务信息
fetch-registry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
此时进入服务中心就需要账号密码了
安全模式下的客户端
此时客户端只需要调整application的配置
spring:
application:
name: base-producer-security
server:
port: 8101
eureka:
client:
service-url:
# 服务发现项目的地址,此时需要将地址配置成 http://<user>:<password>@<ip>:<port>
defaultZone: http://user:123456@localhost:8004/eureka/
logging:
file: ${spring.application.name}.log
defaultZone的地址中填写上密码账号。
然后此时当你尝试连接服务中心的时候,你其实是连接不上服务中心的ε=(´ο`*)))唉
2019-07-04 20:59:06.686 WARN 19652 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_BASE-PRODUCER-SECURITY/YLMF-1806030024:base-producer-security:8101 - 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_172]
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) [na:1.8.0_172]
at java.util.concurrent.FutureTask.run(FutureTask.java) [na:1.8.0_172]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_172]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_172]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_172]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_172]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_172]
这是因为在springboot2.0之后使用安全组件的时候是默认打开了csrf的安全认证,导致你无法连接服务中心。
解决办法
如何解决网上其实给出了一个解决方案,是创建一个类继承WebSecurityConfigurerAdapter关闭掉csrf.
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
添加这项配置后的确客户端可以将服务注册到服务中心了。但是你会发现再次登录服务中心的时候不需要密码账号了。而且后续服务提供方进行连接的时候也不需要配置密码账号了
http.csrf().disable()
其实是将你的安全认证关闭了。这就和我们配置安全组件的初衷相违背了。
最终的配置
最终使用下面的配置既可以保证登录验证又能够将服务注册到服务中心上。
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}
登录验证依旧存在,不过是另外一种样式
服务已经完成注册
本篇文章涉及的源码下载地址:https://gitee.com/daifylearn/cloud-learn
ps.上述的所有项目都是可以成功运行的。但是在后期为了实现每个应用端口尽量不冲突会有些许调整,而后续某次作死调整结构和名称可能会导致部分项目无法运行o(╯□╰)o,如果发现请留言我进行修改。