spring boot:用spring security加强spring boot admin的安全(spring boot admin 2.3.0 / spring boot 2.3.3)

一,spring boot admin的安全环节:

1,修改context-path,默认时首页就是admin,

  我们修改这个地址可以更安全

2,配置ip地址白名单,有ip限制才安全,

  我们使用了spring security,

  可以在防火墙中也配置上ip限制

3,登录用户有相应的role授权才能访问

4,actuator端也要配置ip/路径/权限

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

         对应的源码可以访问这里获取: https://github.com/liuhongdi/

说明:作者:刘宏缔 邮箱: 371125307@qq.com


二,演示项目的相关信息

1,项目地址:

https://github.com/liuhongdi/bootadmin

2,项目功能说明:

        演示了spring boot admin 服务端和actuator客户端的安全配置

3,项目结构;如图:

三,配置文件说明

1,admin模块的pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--admin sever-->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!-- spring security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

2,actuator模块的pom.xml

        <!--admin client-->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!--actuator begin-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- spring security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

3,admin模块的application.properties

#admin context-path
spring.boot.admin.context-path=/lhdadmin
#admin white ip list
spring.boot.admin.access.iplist=192.168.3.1,127.0.0.1
#admin status intertal
spring.boot.admin.monitor.status-interval=60000ms
spring.boot.admin.monitor.status-lifetime=60000ms

#error
server.error.include-stacktrace=always
#error
logging.level.org.springframework.web=trace

4,actuator模块的application.properties

#admin url
spring.boot.admin.client.url=http://localhost:8080/lhdadmin
spring.boot.admin.client.username=lhdadmin
spring.boot.admin.client.password=123456
spring.boot.admin.client.connect-timeout=5000ms
spring.boot.admin.client.period=60000ms
spring.boot.admin.client.instance.metadata.user.name=lhdadmin
spring.boot.admin.client.instance.metadata.user.password=123456
#port
server.port=8081
#exposure
management.endpoints.web.exposure.include=*
#路径映射
management.endpoints.web.base-path=/lhdmon
#health显示
management.endpoint.health.show-details=always
#允许访问的ip列表
management.access.iplist = 127.0.0.1,192.168.1.100,192.168.2.3/24,192.168.1.6,localhost
#error
server.error.include-stacktrace=always
#error
logging.level.org.springframework.web=trace

说明:

spring.boot.admin.client.username=lhdadmin
spring.boot.admin.client.password=123456

这两项是用来访问server的账号

spring.boot.admin.client.instance.metadata.user.name=lhdadmin
spring.boot.admin.client.instance.metadata.user.password=123456

这两项是供server访问actuator时使用

spring.boot.admin.client.url=http://localhost:8080/lhdadmin

此处注意使用服务端设置的context-path

四,java代码说明

1,admin模块的application:DemoApplication.java

@SpringBootApplication
@EnableAdminServer
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

注意添加了@EnableAdminServer注解,用来启动admin sever

2,admin模块的SecurityConfig.java

@Configuration
@EnableWebSecurity
 public class SecurityConfig extends WebSecurityConfigurerAdapter {

     @Value("${spring.boot.admin.access.iplist}")
     private String iplist;

     @Override
     protected void configure(HttpSecurity http) throws Exception {

                 //得到iplist列表
                String iprule = "";
                //hasIpAddress('10.0.0.0/16') or hasIpAddress('127.0.0.1/32')
                String[] splitAddress=iplist.split(",");
                for(String ip : splitAddress){
                     if (iprule.equals("")) {
                         iprule = "hasIpAddress('"+ip+"')";
                     } else {
                         iprule += " or hasIpAddress('"+ip+"')";
                     }
                }
                String adminRule = "hasAnyRole('ADMIN','DEV') and ("+iprule+")";
                  //login和logout
                  http.formLogin()
                          .loginPage("/lhdadmin/login")
                         .defaultSuccessUrl("/lhdadmin/wallboard")
                        .failureUrl("/login-error.html")
                        .permitAll()
                       .and()
                       .logout().logoutUrl("/lhdadmin/logout").permitAll()
                       .and()
                       .httpBasic();

         http.csrf()
                 .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                 .ignoringAntMatchers(
                         "/lhdadmin/**",
                         "/actuator/**"
                 );
                  //匹配的页面,符合限制才可访问
                  http.authorizeRequests()
                  .antMatchers("/lhdadmin/login/**","/lhdadmin/assets/**").access(iprule)
                  .antMatchers("/lhdadmin/**").access(adminRule);
                  //剩下的页面,允许访问
                 http.authorizeRequests().anyRequest().permitAll();
             }
             
     @Autowired
     public  void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
         //添加两个账号用来做测试
         auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                 .withUser("lhdadmin")
                 .password(new BCryptPasswordEncoder().encode("123456"))
                 .roles("ADMIN","USER")
                 .and()
                 .withUser("lhduser")
                 .password(new BCryptPasswordEncoder().encode("123456"))
                 .roles("USER");
     }
 }

3,actuator模块的SecurityConfig.java

@Configuration
@EnableWebSecurity
 public class SecurityConfig extends WebSecurityConfigurerAdapter {


     @Value("${management.access.iplist}")
     private String iplist;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        //得到iplist列表
        String iprule = "";
        String[] splitAddress=iplist.split(",");
        for(String ip : splitAddress){
            if (iprule.equals("")) {
                iprule = "hasIpAddress('"+ip+"')";
            } else {
                iprule += " or hasIpAddress('"+ip+"')";
            }
        }
        String actuatorRule = "hasAnyRole('ADMIN','DEV') and ("+iprule+")";

        //login和logout
        http.formLogin()
                .defaultSuccessUrl("/lhdmon")
                .failureUrl("/login-error.html")
                .permitAll()
                .and()
                .logout()
                .and()
                .httpBasic();
        //匹配的页面,符合限制才可访问
        http.authorizeRequests()
                .antMatchers("/lhdmon/**").access(actuatorRule);
        //剩下的页面,允许访问
        http.authorizeRequests().anyRequest().permitAll();
    }
    
    @Autowired
    public  void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        //添加两个账号用来做测试
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("lhdadmin")
                .password(new BCryptPasswordEncoder().encode("123456"))
                .roles("ADMIN","USER")
                .and()
                .withUser("lhduser")
                .password(new BCryptPasswordEncoder().encode("123456"))
                .roles("USER");
    }
 }

五,测试效果

1,spring boot admin 非授权ip地址访问

http://192.168.3.182:8080/lhdadmin/wallboard

登录后返回:

2,spring boot admin 非授权账号访问

http://127.0.0.1:8080/lhdadmin/login

页面:用lhduser登录

lhduser这个账号无权访问

3,spring boot admin从授权ip用有授权账号登录:

http://127.0.0.1:8080/lhdadmin/login

用lhdadmin这个账号登录:

 跳转到了wallboard

 点击进入:

六,查看spring boot的版本

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _    
( ( )\___ | '_ | '_| | '_ / _` |    
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.3.RELEASE)
原文地址:https://www.cnblogs.com/architectforest/p/13567129.html