SpringCloudGateway中对admin端点进行认证
- 游戏开发
- 2025-07-21 19:15:37

前言
我们被扫了一个漏洞,SpringBoot Actuator 未授权访问,漏洞描述是这样的: Actuator 是 springboot 提供的用来对应用系统进行自省和监控的功能模块,借助于 Actuator 开发者可以很方便地对应用系统某些监控指标进行查看、统计等。在 Actuator 启用的情况下,如果没有做好相关权限控制,非法用户可通过访问默认的执行器端点(endpoints)来获取应用系统中的监控信息,从而导致信息泄露甚至服务器被接管的事件发生
正文如果没有对admin的端点进行鉴权,那么对于开放的网关服务,可以直接通过xx/actuator访问,这将是非常危险的,如果你还暴露了所有端点,那么还可以获取环境中的账号密码信息,即使admin做了脱敏。 要对端点进行鉴权,也非常简单,只需要要引入spring-security依赖即可,下面是Spring Cloud Gateway中的配置。
1、引入xml依赖 spring-boot-starter-web scope 是provided,引入gateway中不能有web
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <scope>provided</scope> </dependency>2、针对Admin端点认证的配置,只对/actuator/**进行认证,其他地址放行,使用业务自身认证。
package com.frame.ops.admin.client.config; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; /** * 对客户端的actuator接口进行鉴权 * 引入后,gateway 有性能问题 */ @EnableWebFluxSecurity @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) public class ReactiveAdminSecurityConfig { @Bean @Order(1) public SecurityWebFilterChain authorizationServerSecurityFilterChain(ServerHttpSecurity http) { http.authorizeExchange() //只对actuator接口认证 .pathMatchers("/actuator/**").authenticated() .anyExchange().permitAll() .and().httpBasic().and().csrf().disable(); return http.build(); } }3、如果是Servlet,配置为
package com.frame.ops.admin.client.config; import org.apache mons.logging.Log; import org.apache mons.logging.LogFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.util.StringUtils; import java.util.List; import java.util.regex.Pattern; /** * 对客户端的actuator接口进行鉴权 */ @Order(1) @EnableWebSecurity @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) public class AdminSecurityConfig extends WebSecurityConfigurerAdapter { //这个InMemoryUserDetailsManager,如果你的业务中也使用了spring security,那么需要自定义一 //个,防止admin认证使用自定义的处理逻辑 @Autowired private InMemoryUserDetailsManager inMemoryUserDetailsManager; private static final String NOOP_PASSWORD_PREFIX = "{noop}"; private static final Pattern PASSWORD_ALGORITHM_PATTERN = Pattern pile("^\\{.+}.*$"); private static final Log logger = LogFactory.getLog(AdminSecurityConfig.class); @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(inMemoryUserDetailsManager); } @Bean public InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties, ObjectProvider<PasswordEncoder> passwordEncoder) { SecurityProperties.User user = properties.getUser(); List<String> roles = user.getRoles(); return new InMemoryUserDetailsManager( User.withUsername(user.getName()).password(getOrDeducePassword(user, passwordEncoder.getIfAvailable())) .roles(StringUtils.toStringArray(roles)).build()); } private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) { String password = user.getPassword(); if (user.isPasswordGenerated()) { logger.warn(String.format( "%n%nUsing generated security password: %s%n%nThis generated password is for development use only. " + "Your security configuration must be updated before running your application in " + "production.%n", user.getPassword())); } if (encoder != null || PASSWORD_ALGORITHM_PATTERN.matcher(password).matches()) { return password; } return NOOP_PASSWORD_PREFIX + password; } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests() //只有actuator开头的请求才需要认证 .antMatchers("/actuator/**").authenticated() .anyRequest().permitAll() .and().httpBasic(); } } 总结⁉️ 奇怪的事来了,在本地测试gateway 请求正常,访问/actuator端点需要认证,但是在服务器上测试一些业务接口就会卡住超时,请求也没到下游服务,过段时间后gateway 假死,任何请求不通。
这个问题只发生在gateway中,对应servlet并没有发现这个问题,不清楚跟Gateway 使用Reactive 有没有关系, 这个问题暂未解决。但也不影响处理漏洞,只要去掉admin依赖,actuator依赖就行了。
作者其他要推荐的文章,欢迎来学习: Prometheus 系列文章
Prometheus 的介绍和安装直观感受PromQL及其数据类型PromQL之选择器和运算符PromQL之函数Prometheus 告警机制介绍及命令解读Prometheus 告警模块配置深度解析Prometheus 配置身份认证Prometheus 动态拉取监控服务Prometheus 监控云Mysql和自建MysqlGrafana 系列文章,版本:OOS v9.3.1
Grafana 的介绍和安装Grafana监控大屏配置参数介绍(一)Grafana监控大屏配置参数介绍(二)Grafana监控大屏可视化图表Grafana 查询数据和转换数据Grafana 告警模块介绍Grafana 告警接入飞书通知SpringCloudGateway中对admin端点进行认证由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“SpringCloudGateway中对admin端点进行认证”