Eureka安全配置
2026/1/15大约 3 分钟EurekaSpring Security安全
Eureka 安全配置
一、为什么需要安全配置
Eureka Server 默认没有认证机制,任何人都可以:
- 访问 Eureka 控制台
- 注册/注销服务
- 获取服务列表
在生产环境中,这是不安全的。
二、添加 Spring Security
2.1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>2.2 配置用户名密码
spring:
security:
user:
name: admin
password: 1234562.3 安全配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 关闭 CSRF(Eureka Client 注册需要)
http.csrf().ignoringRequestMatchers("/eureka/**");
// 开启认证
http.authorizeHttpRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
return http.build();
}
}三、客户端配置
3.1 配置认证信息
eureka:
client:
service-url:
# 格式:http://用户名:密码@主机:端口/eureka/
defaultZone: http://admin:123456@localhost:8761/eureka/3.2 集群配置
# Eureka Server 1
eureka:
client:
service-url:
defaultZone: http://admin:123456@eureka2:8762/eureka/,http://admin:123456@eureka3:8763/eureka/四、HTTPS 配置
4.1 生成证书
# 生成 keystore
keytool -genkeypair -alias eureka -keyalg RSA -keysize 2048 \
-storetype PKCS12 -keystore eureka.p12 -validity 3650 \
-storepass 123456 -keypass 123456 \
-dname "CN=localhost,OU=Dev,O=Company,L=City,ST=State,C=CN"4.2 服务端配置
server:
port: 8761
ssl:
enabled: true
key-store: classpath:eureka.p12
key-store-password: 123456
key-store-type: PKCS12
key-alias: eureka
eureka:
instance:
hostname: localhost
secure-port-enabled: true
secure-port: ${server.port}
non-secure-port-enabled: false
client:
service-url:
defaultZone: https://admin:123456@localhost:8761/eureka/4.3 客户端配置
eureka:
client:
service-url:
defaultZone: https://admin:123456@localhost:8761/eureka/4.4 信任证书配置
@Configuration
public class SslConfig {
@Bean
public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs()
throws Exception {
DiscoveryClient.DiscoveryClientOptionalArgs args =
new DiscoveryClient.DiscoveryClientOptionalArgs();
// 配置 SSL 上下文
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(new TrustSelfSignedStrategy())
.build();
args.setSSLContext(sslContext);
return args;
}
}五、IP 白名单
5.1 自定义过滤器
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class IpWhitelistFilter implements Filter {
private static final Set<String> WHITELIST = Set.of(
"127.0.0.1",
"192.168.1.0/24"
);
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String clientIp = getClientIp(httpRequest);
if (isAllowed(clientIp)) {
chain.doFilter(request, response);
} else {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
httpResponse.getWriter().write("IP not allowed: " + clientIp);
}
}
private String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty()) {
ip = request.getRemoteAddr();
}
return ip;
}
private boolean isAllowed(String ip) {
return WHITELIST.stream().anyMatch(pattern -> matchIp(ip, pattern));
}
private boolean matchIp(String ip, String pattern) {
// 实现 IP 匹配逻辑(支持 CIDR)
if (pattern.contains("/")) {
// CIDR 匹配
return matchCidr(ip, pattern);
}
return ip.equals(pattern);
}
}六、审计日志
6.1 记录注册/注销事件
@Component
public class EurekaEventListener {
private static final Logger log = LoggerFactory.getLogger(EurekaEventListener.class);
@EventListener
public void onInstanceRegistered(EurekaInstanceRegisteredEvent event) {
InstanceInfo instance = event.getInstanceInfo();
log.info("服务注册: {} - {}:{}",
instance.getAppName(),
instance.getIPAddr(),
instance.getPort());
}
@EventListener
public void onInstanceCanceled(EurekaInstanceCanceledEvent event) {
log.info("服务下线: {} - {}",
event.getAppName(),
event.getServerId());
}
@EventListener
public void onInstanceRenewed(EurekaInstanceRenewedEvent event) {
log.debug("服务续约: {} - {}",
event.getAppName(),
event.getServerId());
}
}七、限流配置
7.1 添加限流依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>7.2 限流过滤器
@Component
public class RateLimitFilter implements Filter {
// 每秒最多 100 个请求
private final RateLimiter rateLimiter = RateLimiter.create(100);
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (rateLimiter.tryAcquire()) {
chain.doFilter(request, response);
} else {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
httpResponse.getWriter().write("Too many requests");
}
}
}八、安全最佳实践
8.1 生产环境配置清单
| 配置项 | 建议 |
|---|---|
| 认证 | 启用 Spring Security |
| HTTPS | 生产环境必须启用 |
| 密码 | 使用强密码,定期更换 |
| 网络 | 内网部署,限制外网访问 |
| 日志 | 开启审计日志 |
| 监控 | 配置告警 |
8.2 完整安全配置示例
server:
port: 8761
ssl:
enabled: true
key-store: classpath:eureka.p12
key-store-password: ${KEYSTORE_PASSWORD}
key-store-type: PKCS12
spring:
application:
name: eureka-server
security:
user:
name: ${EUREKA_USER:admin}
password: ${EUREKA_PASSWORD}
eureka:
instance:
hostname: ${HOSTNAME:localhost}
secure-port-enabled: true
secure-port: ${server.port}
non-secure-port-enabled: false
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: https://${spring.security.user.name}:${spring.security.user.password}@eureka2:8762/eureka/
server:
enable-self-preservation: true
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
show-details: when_authorized九、总结
安全配置要点:
- 认证:启用 Spring Security
- 加密:生产环境使用 HTTPS
- 访问控制:IP 白名单、限流
- 审计:记录关键操作日志
