当前位置:   article > 正文

SpringBoot Admin的简单使用_spring boot3 admin security

spring boot3 admin security

公司有个SpringBoot项目需要加个监控,网上找了下发现大家都在推荐SpringBootAdmin。SpringBoot Admin是开源社区孵化的项目,用于对SpringBoot应用的管理和监控。SpringBoot Admin 分为服务端(spring-boot-admin-server)和客户端(spring-boot-admin-client),服务端和客户端之间采用http通讯方式实现数据交互;单体项目中需要整合spring-boot-admin-client才能让应用被监控。在SpringCloud项目中,spring-boot-admin-server 是直接从注册中心抓取应用信息,不需要每个微服务应用整合spring-boot-admin-client就可以实现应用的管理和监控。

    官网参考链接:Spring Boot Admin Reference Guide

    本文只叙述SpringBoot Admin 管理和监控单体应用 ,不涉及SpringCloud相关的内容 。

一、快速入门

1.1 SpringBoot Admin服务端的搭建

(1) Maven依赖说明

    SpringBoot版本

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.2.10.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>

 添加SpringBootAdmin server依赖及SpringBoot web 依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <!--这里由于我的springboot版本是2.2.10.RELEASE,所以 springboot admin 也要用2.2.x版-->
  6. <dependency>
  7. <groupId>de.codecentric</groupId>
  8. <artifactId>spring-boot-admin-starter-server</artifactId>
  9. <version>2.2.4</version>
  10. </dependency>

(2)application.yml中配置端口

# 指定端口
server:
   port: 23333

(3)编写启动类并开启SpringBootAdminServer

  1. package com.zcode.monitor.server;
  2. import de.codecentric.boot.admin.server.config.EnableAdminServer;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. /**
  6. * AdminServerApplication
  7. * @author ZENG.XIAO.YAN
  8. * @version 1.0
  9. * @Date 2020-11-12
  10. */
  11. @EnableAdminServer // 开启 springboot admin 服务端
  12. @SpringBootApplication
  13. public class AdminServerApplication {
  14. public static void main(String[] args) {
  15. SpringApplication.run(AdminServerApplication.class,args);
  16. }
  17. }

(4)浏览器访问测试

    浏览器访问 http://localhost:23333/  出现以下页面说明SpringBoot Admin服务端搭建成功

 

1.2 SpringBootAdmin client端搭建

    备注:所谓的 client端就是指我们需要被监控的应用端。这里我们写一个简单点的SpringBoot web应用做演示 

(1)Maven依赖说明

    SpringBoot版本如下

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.2.10.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>

添加SpringBootAdmin client 依赖及SpringBoot web 依赖。这里不需要添加SpringBoot actuator 依赖,因为SpringBootAdmin client里面已经包含了actuator相关依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <!--这里由于我的springboot版本是2.2.10.RELEASE,所以 springboot admin 也要用2.2.x版-->
  6. <dependency>
  7. <groupId>de.codecentric</groupId>
  8. <artifactId>spring-boot-admin-starter-client</artifactId>
  9. <version>2.2.4</version>
  10. </dependency>

(2) application.yml配置

在yml中需要 配置如下信息:

    • 应用端口
    • 开放端点用于SpringBootAdmin 监控
    • 配置应用名称(该名称会在SpringBoot Admin的管理页面显示)
    • 配置Admin Server的地址 
    • 配置下日志文件的文件名和存放位置 (如果不配置则会看不到日志)
  1. # 端口
  2. server:
  3. port: 9088
  4. #开放端点用于SpringBoot Admin的监控
  5. management:
  6. endpoints:
  7. web:
  8. exposure:
  9. include: '*'
  10. spring:
  11. application:
  12. name: admin-client # 给client应用取个名字
  13. boot:
  14. admin:
  15. client:
  16. url: http://localhost:23333 #这里配置admin server 的地址
  17. logging:
  18. file:
  19. name: admin-client.log #配置生成日志文件名称

(3)写一个Controller模拟一个普通的接口

    通过浏览器访问这个接口就会打印日志,具体代码如下

  1. /**
  2. * HelloController
  3. *
  4. */
  5. @Slf4j
  6. @RestController
  7. @RequestMapping("api")
  8. public class HelloController {
  9. private AtomicInteger count = new AtomicInteger(0);
  10. @GetMapping("hi")
  11. private String sayHi() {
  12. // 每次进来如打印下日志
  13. log.info("{} 啪...我第{}次进来了.", LocalDateTime.now(), count.addAndGet(1));
  14. // 每次进来new 个大对象,便于监控观察堆内存变化
  15. byte[] bytes = new byte[100*1024*1024];
  16. log.info("new了 100MB");
  17. return "hi springboot addmin " + LocalDateTime.now();
  18. }
  19. }

(4)写个启动类

    启动类代码就很简单了,就是一个普通的SpringBoot项目的启动类,上面没加其他注解。具体如下

  1. @SpringBootApplication
  2. public class AdminClientApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(AdminClientApplication.class, args);
  5. }
  6. }

1.3 效果展示

(1)已管理的应用会在应用墙上展示

     当我们的admin-client项目启动后,在 admin-server的管理页面的应用墙上就能看到admin-client这个应用了,具体可参考下图

 

(2)可查看应用的具体信息

    在应用墙点击这个应用,我们可以看到这个应用的具体信息,如堆内存变化及线程数等。具体可参考下图

 

(3)日志查看及堆内存变化观察

    请求我们在admin-client中写的模拟接口 http://localhost:9088/api/hi  ,该接口请求一次则会输出日志,同时开辟100MB的堆内存空间。

    请求多次后在网页上可以实时的看到日志如下图

 由于我们直接new了100MB的大对象,此时可以查看细节中的堆内存变化;具体如下图 

 

二、安全性

2.1 admin-server端安全加固

    这个SpringBoot Admin的管理后台如果没密码就能访问,那实在太不安全了,因此我们要给它加上登录的功能。

参考SpringBoot Admin的官方文档,我们可以在Admin-Server端添加Spring Security 相关依赖及就可以实现需要登录后才能访问网页管理面板。

    官网参考链接为:Spring Boot Admin Reference Guide

    下面开始具体的改造

(1)admin-server 添加Spring Security 相关依赖

  1. <!--springboot admin 安全相关-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-security</artifactId>
  5. </dependency>

(2)admin-server 设置账号和密码

    在application.yml配置账号和密码

  1. # 配置一个账号和密码
  2. spring:
  3. security:
  4. user:
  5. name: admin
  6. password: root123456

(3)admin-server 添加一个Spring Security 配置类

  1. @Configuration
  2. public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
  3. private final String adminContextPath;
  4. public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
  5. this.adminContextPath = adminServerProperties.getContextPath();
  6. }
  7. @Override
  8. protected void configure(HttpSecurity http) throws Exception {
  9. SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
  10. successHandler.setTargetUrlParameter("redirectTo");
  11. successHandler.setDefaultTargetUrl(adminContextPath + "/");
  12. http.authorizeRequests()
  13. //1.配置所有静态资源和登录页可以公开访问
  14. .antMatchers(adminContextPath + "/assets/**").permitAll()
  15. .antMatchers(adminContextPath + "/login").permitAll()
  16. .anyRequest().authenticated()
  17. .and()
  18. //2.配置登录和登出路径
  19. .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
  20. .logout().logoutUrl(adminContextPath + "/logout").and()
  21. //3.开启http basic支持,admin-client注册时需要使用
  22. .httpBasic().and()
  23. .csrf()
  24. //4.开启基于cookie的csrf保护
  25. .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
  26. //5.忽略这些路径的csrf保护以便admin-client注册
  27. .ignoringAntMatchers(
  28. adminContextPath + "/instances",
  29. adminContextPath + "/actuator/**"
  30. );
  31. }
  32. }

(4)admin-server 安全加固后访问测试

    再次访问http://localhost:23333/  ,发现需要登录

 当我们输入正确的账号密码登录后,情况如下图

 

 这个时候的应用数居然变成了0了,在我们没进行安全加固时是有一个admin-client应用的,为什么就不见了?

    原因是添加了账号密码认证后,admin-client端也需要配置下 admin-server的账号和密码。

(5)admin-client 端设置 admin-server的账号密码

    admin-client 注册到 admin-server时,admin-server端有个http Basic认证,通过了认证后 admin-client才能注册到 admin-server上。

    admin-client的application.yml中配置访问密码配置可参考下面代码

  1. spring:
  2. application:
  3. name: admin-client # 给client应用取个名字
  4. boot:
  5. admin:
  6. client:
  7. url: http://localhost:23333 #这里配置admin server 的地址
  8. # 配置 admin-server的账号和密码
  9. username: admin
  10. password: root123456

(6) 再次访问 admin-server 管理后台

    当我们登录后,终于再次看到了我们的admin-client这个应用

 

2.2 admin-client端的安全

    admin-client端如果把actuator 端点都暴露出来,是非常不安全的。因此我们可以添加Spring Security对admin-client 也进行安全加固。

    下面所有操作均在admin-client中进行

(1)添加Spring Security依赖

  1. <!--spring security-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-security</artifactId>
  5. </dependency>

(2)yml配置

    yml中需要设置client的账号和密码,官网相关配置如下图所示

 本次演示的admin-client的相关yml配置参考下面代码

 

  1. spring:
  2. application:
  3. name: admin-client # 给client应用取个名字
  4. boot:
  5. admin:
  6. client:
  7. url: http://localhost:23333 #这里配置admin server 的地址
  8. # 配置 admin-server的账号和密码
  9. username: admin
  10. password: root123456
  11. instance:
  12. metadata:
  13. # 这里配置admin-client的账号和密码
  14. user.name: ${spring.security.user.name}
  15. user.password: ${spring.security.user.password}
  16. # admin-client 的用户名和密码
  17. security:
  18. user:
  19. name: clientAdmin
  20. password: 123456

(3)添加Spring Security 配置类

    为何要到配置?因为Spring Security不配置时会把所有请求都拦截的,而我们这里只需要拦截监控端点/actuator/**即可。同时,官网中提到admin-server访问admin-client时,也是采用http Basic认证方式的;因此需要配置Spring Security支持Http Basic认证方式。

  1. @Configuration
  2. @Slf4j
  3. public class SpringSecurityActuatorConfig extends WebSecurityConfigurerAdapter {
  4. public SpringSecurityActuatorConfig() {
  5. log.info("SpringSecurityActuatorConfig... start");
  6. }
  7. @Override
  8. protected void configure(HttpSecurity http) throws Exception {
  9. // 这个配置只针对 /actuator/** 的请求生效
  10. http.antMatcher("/actuator/**")
  11. // /actuator/下所有请求都要认证
  12. .authorizeRequests().anyRequest().authenticated()
  13. // 启用httpBasic认证模式,当springboot admin-client 配置了密码时,
  14. // admin-server走httpbasic的认证方式来拉取client的信息
  15. .and().httpBasic()
  16. // 禁用csrf
  17. .and().csrf().disable();
  18. }
  19. }

(4)效果展示

    admin-server端依旧能看到admin-client的信息,说明我们添加SpringSecurity 后 admin-server的监控管理功能正常,具体见下图

当我们去访问admin-client的监控端点 http://localhost:9088/actuator/health 时,发现需要进行http Basic认证;这也证明了我们的认证拦截只拦截了监控端点。效果如下图

 

(5)存在的问题

    通过上面的一通配置,admin-client 添加 Spring Security 对actuator的端点进行安全认证的功能是实现了,但也存在着问题。

    当我们项目本来就是使用SpringSecurity 安全框架进行认证和授权时。上述的配置就要做修改了。因为我们一般都不用HttpBasic认证,而是用的表单登录认证。也就出现了配置多个Spring Security的问题。虽然有这个问题,但是网上还是有解决方案的。

(6)多个Spring Security共存方案

    这个方案是在Spring Security官方文档里面找到的

    链接为: Spring Security Reference 

    官网关键信息截图如下:

    里面的重点就是通过添加Order注解来指定多个Spring Security的优先级

    下面直接贴上我的代码;为了直观,我就在同一个类里面建了2个静态的Spring Security配置类

  1. /**
  2. * SpringSecurity 表单和HttpBasic 共存配置参考,写在一个类里面方便对比
  3. */
  4. @Slf4j
  5. public class SpringSecurityConfig2 {
  6. /*
  7. * 这个表单和HttpBasic 共存配置玩法,参考url如下:
  8. * 官方url:https://docs.spring.io/spring-security/site/docs/4.2.3.BUILD-SNAPSHOT/reference/htmlsingle/#multiple-httpsecurity
  9. * 项目启动日志如下,可以看到创建了2条过滤链
  10. * 2020-11-11 22:57:56.340 INFO 12692 --- [main] o.s.s.web.DefaultSecurityFilterChain: Creating filter chain: Ant [pattern='/actuator/**'],
  11. * 2020-11-11 22:57:56.344 INFO 12692 --- [main] o.s.s.web.DefaultSecurityFilterChain: Creating filter chain: any request,
  12. */
  13. /**
  14. * HttpBasic 认证方式,只对/actuator/** 生效,由于设置了Order,优先级会高于FormLoginWebSecurityConfigurerAdapter
  15. * @author ZENG.XIAO.YAN
  16. * @Date 2020-11-11
  17. * @version 1.0
  18. */
  19. @Configuration
  20. @Order(1)
  21. public static class HttpBasicSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
  22. public HttpBasicSecurityConfigurationAdapter() {
  23. log.info("HttpBasicSecurityConfigurationAdapter... start");
  24. }
  25. protected void configure(HttpSecurity http) throws Exception {
  26. // 这个配置只针对 /actuator/** 的请求生效
  27. http.antMatcher("/actuator/**")
  28. // /actuator/下所有请求都要认证
  29. .authorizeRequests().anyRequest().authenticated()
  30. // 启用httpBasic认证模式,当springboot admin-client 配置了密码时,
  31. // admin-server走httpbasic的认证方式来拉取client的信息
  32. .and().httpBasic()
  33. // 禁用csrf
  34. .and().csrf().disable();
  35. }
  36. }
  37. /**
  38. * 表单登录认证方式配置,由于没有指定Order,所以默认是最大2147483647,数值越大,优先级越低
  39. * @author ZENG.XIAO.YAN
  40. * @Date 2020-11-11
  41. * @version 1.0
  42. */
  43. @Configuration
  44. public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
  45. public FormLoginWebSecurityConfigurerAdapter() {
  46. log.info("FormLoginWebSecurityConfigurerAdapter... start");
  47. }
  48. @Override
  49. protected void configure(HttpSecurity http) throws Exception {
  50. http.authorizeRequests()
  51. .anyRequest().authenticated()
  52. .and()
  53. .formLogin();
  54. }
  55. }
  56. }

    添加完这个配置类后,记得把我们上面配置的SpringSecurityActuatorConfig 这个类删除了,然后重启项目。效果如下:

    访问 http://localhost:9088/actuator/health ,则出现的是httpBasic认证的页面

 

访问 http://localhost:9088/api/hi ,则出现的是Spring Security 自带的表单登录页面

     访问admin-server 的管理页面,发现admin-client应用信息正常,说明本次修改的Spring Security配置没有问题

 

三、小结

(1)本文介绍了SpringBoot Admin的简单使用,同时介绍了admin-server端的安全配置和admin-client端的安全配置

(2)在介绍admin-client端的安全配置时,引申出了 如何实现多个SpringSecurity 配置 共存

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/183948
推荐阅读
相关标签
  

闽ICP备14008679号