Eureka Server默认是允许匿名访问的,该方式一般无法满足公司在安全性上的诉求.
接下来我们构建一个需要登录才能访问的Eureka Server. Eureka本身不具备安全认证的能力,Spring Cloud使用Spring Security为Eureka Server进行了增强.
1. 添加security依赖在Eureka Server项目中引入Springboot提供的安全认证依赖包包,在服务提供者和消费者代码中不用引入.
org.springframework.boot
spring-boot-starter-security
2. 配置用户名密码
在application.yml文件中配置相关信息.
server:
port: 8761
spring:
application:
name: eurka-server
security: #eureka的身份认证
user:
name: admin
password: 123
eureka:
server:
enable-self-preservation: true #关闭自我保护机制
eviction-interval-timer-in-ms: 5000 #(代表是5秒,单位是毫秒,清理失效服务的间隔)
instance:
hostname: localhost
#调整自我保护机制的参数
lease-renewal-interval-in-seconds: 1
lease-expiration-duration-in-seconds: 2
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
defaultZone: http://admin:123@localhost:8761/eureka/
如果不设置用户名密码这段内容,则默认用户名是user,密码是一个随机值,该值会在启动时打印出来.
并且将Eureka Server中的 eureka.client.service-url.defaultZone
修改为为http://{user}:{password}@EUREKA_HOST:EUREKA_PORT/eureka/
的形式.
eureka:
client:
service-url:
defaultZone: http://admin:123@localhost:8761/eureka/
如图所示:
package com.syc.cloud.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* Spring Cloud Finchley及更高版本,必须添加如下代码以用来部分关闭掉Spring Security
* 的CSRF保护功能,否则应用无法正常注册.
* Spring Cloud Finchley及更高版本必须添加这一段,在Edgware以及更早的版本中无需这一步骤.
*/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//忽略掉/eureka/相关接口的安全拦截
http.csrf()
.ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
Spring Cloud Finchley及更高版本必须添加这一段,在Edgware以及更早的版本中无需这一步骤.
4. 启动Eureka Server
接下来需要改造Eureka Client项目模块.我们需要将eureka.client.service-url.defaultZone
配置为http://{user}:{password}@EUREKA_HOST:EUREKA_PORT/eureka/
的形式.
eureka:
client:
serviceUrl:
defaultZone: http://admin:123@localhost:8761/eureka/
二. Eureka的数据权限
实际项目中,出于安全考虑,往往还需实现数据权限.
1. 举个例子-
团队1维护微服务A、B、C;
-
团队2维护微服务D、E、F.
-
团队1中的开发人员只能操作微服务A、B、C在Eureka Server上的信息;
-
团队1中的开发人员只能访问其他团队授权给该团队的微服务的信息(例如团队2将微服务D授权给微服务A访问).
一般Eureka Server上都没有什么操作,在整个Eureka Server的界面上,一般只有查看的能力!
如果只是查看,自然没有安全问题,但是要知道Eureka Server是有RESTful API的.举个例子,我们可以发送DELETE请求到http://{username}:{password}@EUREKA_HOST:EUREKA_PORT/eureka/apps/{appId}/{instanceID}
,即可下线服务.如果线上微服务被恶意下线,那后果是不堪设想的.
Spring Cloud的原生Eureka Server并未提供这一功能,只能由开发人员基于Spring Security或其他权限框架自行扩展.
这个扩展的成本还是比较高的,于是目前业界大多企业都放弃了扩展,转而采用管理手段防止无数据权限带来的风险.例如在生产环境中:
-
1️⃣. 将Eureka Server的账号密码管控起来,只有核心成员才知晓;
-
2️⃣. 然后在配置中心把账号密码等敏感数据进行加密存储.
-
3️⃣. 将Eureka Server部署在一个隔离的网络中,外人无法直接访问到Eureka Server首页,必须借助跳板机等工具才能访问.
但不管怎么样,以上方式都会增加运维成本,同时也会带来不少沟通问题.
4. 所以一般体验最好、最直观、最完美的做法如下:-
1️⃣. 有完备的数据权限机制;
-
2️⃣. 开发人员在一个Dashboard上可以查看、管理所有他有权管理的微服务(这里的Dashboard并不是指Eureka Server的界面,而是自己另外做的界面);
-
3️⃣. 在Dashboard的某个地方能直接切换环境,例如一键切换开发、测试、生产环境等.
POST /eureka/apps/{appId} 注册新的实例
DELETE /eureka/apps/{appId}/{instanceId} 注销应用实例
PUT /eureka/apps/{appId}/{instanceId} 应用实例发送心跳
GET /eureka/apps 查询所有的实例
GET /eureka/apps/{appId} 查询指定appId的实例
GET /eureka/apps/{appId}/{instanceId} 查询指定appId和instanceId的实例
GET /eureka/instances/{instanceId} 查询指定的instanceId的实例
PUT /eureka/apps/{appId}/{instanceId}/status?value=OUT_OF_SERVICE 暂停应用实例
PUT /eureka/apps/{appId}/{instanceId}/status?value=UP 恢复应用实例
PUT /eureka/apps/{appId}/{instanceId}/metadata?key=value 更新元数据信息
GET /eureka/vips/{vipAddress} 根据vip地址查询
GET /eureka/svips/{svipAddress} 根据svip地址查询