Spring Boot Admin非Spring官方出品(以下简称SBA),用于管理和监控SpringBoot应用程序。深度与Spring Boot的集成,展示应用的Spring Boot的配置参数,并可以动态调整。 SBA的官方文档比较详细了。网上的文档也很多,本文的主要是填坑记录。
对安全方面的我觉得至少得有个最简单的登录验证,这需要集成spring security,官网文档里写的很详细。
搭建Spring Boot Admin服务端
这里需要搭建SBA服务端的项目,保持了对服务端的灵活度外
使用的springboot版本较新,使用了log4j2日志,pom关键配置如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
需要设置登录验证和跳转
@Configuration
@EnableAutoConfiguration
@EnableAdminServer
public class SpringBootAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminApplication.class, args);
}
@Configuration
public static class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers(
adminContextPath + "/instances",
adminContextPath + "/actuator/**"
);
}
}
application.yml
server:
port: 8080
spring:
application:
name: "@project.artifactId@"
security:
user:
name: admin_user
password: admin_password
项目集成Spring Boot Admin客户端
修改pom加入相关
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
修改application.yml
注意
spring.boot.admin.client的访问用户和密码设置与server端一致- SBA的client的用户和密码位于
spring.security.user节点, - 还需要通过
spring.boot.admin.client.instance.metadata.user暴露客户端用户密码给服务端,否则服务无法访问客户端获取指标数据
spring:
application.name: "@project.artifactId@"
security.user:
name: actuator_user
password: password1
roles: ENDPOINT_ACTUATOR
boot.admin.client:
url: http://x.x.x.x:8080
username: admin_user
password: admin_password
instance:
prefer-ip: true
metadata.user:
name: actuator_user
password: actuator_password
加入权限校验配置的Java代码
这样在浏览器中访问客户端的/actuator时会弹出基础认证的对话框,要求输入用户名密码。
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration(proxyBeanMethods = false)
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint())
.authorizeRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ACTUATOR"))
.httpBasic();
}
}
使用FastJson的注意点
由于Actuator使用的是jackson作消息转化,jackson的@JsonProperty。如果我们使用了FastJson作为消息转化器,无法识别其@JsonProperty,不能转化属性映射(参见:fastJson的@JSONField和jackson的@JsonProperty使用)。导致监控健康状态显示不全。
另外一点,需要加入Actuator的设定的MediaType,否则会出现406错误。
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.PrettyFormat,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteEnumUsingToString,
SerializerFeature.WriteNullStringAsEmpty
);
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
fastConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
fastConverter.setFastJsonConfig(fastJsonConfig);
fastConverter.setDefaultCharset(Charset.forName("UTF-8"));
converters.add(fastConverter);
//加入jackson转换器,兼容actuator模块的消息转化,因为它的bean使用了jackson特有的@JsonProperty
MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
jacksonConverter.setObjectMapper(objectMapper);
jacksonConverter.setSupportedMediaTypes(
Arrays.asList(
MediaType.valueOf(ActuatorMediaType.V2_JSON),
MediaType.valueOf(ActuatorMediaType.V3_JSON))
);
converters.add(jacksonConverter);
}
启动Spring Boot Admin 服务端,可以登录进入,图表功能较弱。



3034

被折叠的 条评论
为什么被折叠?



