前言
Spring Boot Admin 是一个优秀的 Spring Boot 应用监控,可以查看应用的各项性能指标,修改日志级别(生产环境利器,不用动不动就上 Arthas),dump 线程等功能。如果是微服务可以使用 Eureka 来做服务的注册与发现,单体应用的话直接往 Spring Boot Admin 的 Server 端注册就行。
这里主要讲认证方面,毕竟生产环境开放接口是件很危险的事。Spring Boot Admin 采用的是 Spring Security,如果项目认证模块本来就用是 Spring Security,那倒简单许多。但如果项目使用的是其他认证框架,就需要配合使用了,这里拿 Shiro 举例。
创建监控服务端
导入依赖
代码语言:javascript复制 <dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
<version>${spring-boot-admin-server.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>${spring-boot-admin-server.version}</version>
</dependency>
<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>
</dependency>
- 服务端需要提供操作界面,这里引入了
spring-boot-admin-server-ui
application.yml
代码语言:javascript复制spring:
security:
user:
name: xxx
password: xxx
- 定义监控服务端的账号密码,用于访问监控管理界面和 Spring Boot Admin 的 Client 注册
启动类
代码语言:javascript复制@EnableAdminServer
@SpringBootApplication
public class MonitorApplication {
public static void main(String[] args) {
SpringApplication.run(MonitorApplication.class, args);
}
}
- EnableAdminServer:启用 Spring Boot Admin 的服务端
监控服务端的认证配置
代码语言:javascript复制@Configuration
@EnableWebSecurity
public 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 handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setTargetUrlParameter("redirectTo");
handler.setDefaultTargetUrl(this.adminContextPath "/");
// 启用HTTP-Basic支持。这是Spring Boot Admin Client注册所必需的
http.httpBasic().and()
// 授予对所有静态资产的公共访问权限
.authorizeRequests().antMatchers(this.adminContextPath "/assets/**").permitAll()
// 授予对登录页面的公共访问权限
.antMatchers(this.adminContextPath "/login").permitAll().and()
// 所有请求都需要验证登录
.authorizeRequests().anyRequest().authenticated().and()
// 登录表单
.formLogin().loginPage(this.adminContextPath "/login").successHandler(handler).and()
// 登出表单
.logout().logoutUrl(this.adminContextPath "/logout").and().csrf()
// Enables CSRF-Protection using Cookies
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).ignoringAntMatchers(
// 将服务注册的接口暴露出去.
this.adminContextPath "/instances",
this.adminContextPath "/actuator/**");
;
}
}
配置被监控的客户端
导入依赖
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin-starter-client.version}</version>
</dependency>
application.yml
代码语言:javascript复制spring:
profiles:
active: test
application:
name: @project.artifactId@-${spring.profiles.active}-${server.port}
# 服务监控 start
boot:
admin:
client:
#指定admin server的地址
url: http://ip:port
#如果admin server设置了密码,admin client也要密码才能注册到admin server上
username: xxx
password: xxx
#以ip注册到admin server上,默认false使用hostname注册
instance:
# 告诉监控saver端,此客户端的地址,默认取的docker内部ip
# 不同环境需要单独配置
service-url: http://ip:${server.port}
prefer-ip: true
metadata:
user:
name: ${spring.security.user.name}
password: ${spring.security.user.password}
security:
user:
name: xxx
password: xxx
management:
#暴露actuator的全部endpoint(即/actuator系列路径),默认只暴露少数endpoint
endpoints:
web:
exposure:
include: "*"
#显示节点健康的具体信息,/actuator/health默认只返回节点状态(up|down),不返回节点的具体信息
endpoint:
health:
show-details: always
# 服务监控 end
- @project.artifactId@-{spring.profiles.active}-{server.port}:定义应用名称,便于监控管理界面区分多节点应用。这里使用了pom.xml里的变量,具体方法可参考Maven构建配置和激活SpringBoot配置文件
配置 Spring Security 对暴露的应用状态信息接口做认证
代码语言:javascript复制@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 监控信息的接口
*/
public static final String ACTUATOR_URL = "/actuator/**";
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(ACTUATOR_URL).authenticated()
.and()
.httpBasic();
}
}
.csrf().disable()
:必须加这个,默认是启用了csrf
,所有接口都会被拦截。我们这个项目是用 Shiro 来做认证模块的,所以 Spring Security 只需要管理应用状态信息接口就行
配置 Shiro ,放行应用状态信息接口
代码语言:javascript复制@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 配置不会被拦截的链接 顺序判断
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 放开监控信息的接口,交给 Spring Security 管理
filterChainDefinitionMap.put(SecurityConfig.ACTUATOR_URL, "anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
访问监控管理界面
访问 Spring Boot Admin 的Server端:http://ip:port/,输入 Server 端配置的账号密码就能使用了。