zoukankan      html  css  js  c++  java
  • spring boot:用spring security加强druid的安全(druid 1.1.22 / spring boot 2.3.3)

    一,druid的安全保障有哪些环节要注意?

    1,druid ui的访问要有ip地址限制

    2,用户必须要有相应的权限才能访问druid

    3,关闭重置功能

    说明:stat-view-servlet.url-pattern的配置应用时会报错,

            如果bug修改了,使用这个功能会更安全

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

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

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

    二,演示项目的相关信息

    1,项目地址:

    https://github.com/liuhongdi/druidsecurity

    2,项目功能说明:

           演示了druid的安全配置

    3,项目结构:如图:

    三,配置文件说明

    1,pom.xml

            <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>
            <!--druid begin-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.22</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-log4j2</artifactId>
            </dependency>
            <dependency>
                <groupId>com.lmax</groupId>
                <artifactId>disruptor</artifactId>
                <version>3.4.2</version>
            </dependency>
            <!--mybatis begin-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.3</version>
            </dependency>
            <!--mysql begin-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
    
            <!-- spring security -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>

    2,application.properties

    #error
    server.error.include-stacktrace=always
    #error
    logging.level.org.springframework.web=trace
    
    #   数据源基本配置
    spring.datasource.username = root
    spring.datasource.password = lhddemo
    spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
    spring.datasource.url = jdbc:mysql://127.0.0.1:3306/store?serverTimezone=UTC
    spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
    
    #   Druid数据源配置
    spring.datasource.druid.initialSize = 5
    spring.datasource.druid.minIdle = 5
    spring.datasource.druid.maxActive = 20
    spring.datasource.druid.maxWait = 60000
    spring.datasource.druid.timeBetweenEvictionRunsMillis = 60000
    spring.datasource.druid.minEvictableIdleTimeMillis = 300000
    spring.datasource.druid.validationQuery = SELECT 1 FROM DUAL
    spring.datasource.druid.testWhileIdle = true
    spring.datasource.druid.testOnBorrow = false
    spring.datasource.druid.testOnReturn = false
    spring.datasource.druid.poolPreparedStatements = true
    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    spring.datasource.druid.filters = stat,wall,log4j2
    spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize = 20
    spring.datasource.druid.useGlobalDataSourceStat = true
    spring.datasource.druid.connectionProperties = druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    
    #druid sql firewall monitor
    spring.datasource.druid.filter.wall.enabled=true
    
    #druid sql monitor
    spring.datasource.druid.filter.stat.enabled=true
    spring.datasource.druid.filter.stat.log-slow-sql=true
    spring.datasource.druid.filter.stat.slow-sql-millis=10000
    spring.datasource.druid.filter.stat.merge-sql=true
    
    #druid uri monitor
    spring.datasource.druid.web-stat-filter.enabled=true
    spring.datasource.druid.web-stat-filter.url-pattern=/*
    spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
    
    #druid session monitor
    spring.datasource.druid.web-stat-filter.session-stat-enable=true
    spring.datasource.druid.web-stat-filter.profile-enable=true
    
    #druid spring monitor
    spring.datasource.druid.aop-patterns=com.druid.*
    
    #monintor
    #druid login user config
    spring.datasource.druid.stat-view-servlet.enabled=true
    #使重置功能不起作用
    spring.datasource.druid.stat-view-servlet.reset-enable=false
    #spring.datasource.druid.stat-view-servlet.url-pattern=/abcd/*
    spring.datasource.druid.stat-view-servlet.login-username=root
    spring.datasource.druid.stat-view-servlet.login-password=root
    # IP白名单 (没有配置或者为空,则允许所有访问)
    spring.datasource.druid.stat-view-servlet.allow = 127.0.0.1,192.168.1.1
    # IP黑名单 (存在共同时,deny优先于allow)
    spring.datasource.druid.stat-view-servlet.deny = 192.168.10.1
    
    #mybatis
    mybatis.mapper-locations=classpath:/mapper/*Mapper.xml
    mybatis.type-aliases-package=com.example.demo.mapper
    mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    
    logging.config = classpath:log4j2.xml

    说明:以下是安全配置的重点

    #使重置功能不起作用
    spring.datasource.druid.stat-view-servlet.reset-enable=false
    #配置访问监控view的用户名密码
    spring.datasource.druid.stat-view-servlet.login-username=root
    spring.datasource.druid.stat-view-servlet.login-password=root
    # IP白名单 (没有配置或者为空,则允许所有访问)
    spring.datasource.druid.stat-view-servlet.allow = 127.0.0.1,192.168.1.1
    # IP黑名单 (存在共同时,deny优先于allow)
    spring.datasource.druid.stat-view-servlet.deny = 192.168.10.1

    四,java代码说明:

    1,SecurityConfig.java

    @Configuration
    @EnableWebSecurity
     public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //针对druid的ui,关闭csrf,否则会无法登录
            http.csrf().ignoringAntMatchers("/druid/**");
    
            //login和logout
            http.formLogin()
                    .defaultSuccessUrl("/goods/session")
                    .failureUrl("/login-error.html")
                    .permitAll()
                    .and()
                    .logout();
    
            //指定访问druid的role
            String druidRule = "hasAnyRole('ADMIN','DEV')";
            //匹配的页面,符合限制才可访问
            http.authorizeRequests()
                    .antMatchers("/druid/**").access(druidRule)
                    .antMatchers("/goods/**").hasAnyRole("ADMIN","DEV","USER");
    
            //剩下的页面,允许访问
            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");
        }
     }

    说明:

          http.csrf().ignoringAntMatchers("/druid/**");

          针对druid关闭csrf,否则会导致无法登录,其他页面不受影响

         antMatchers("/druid/**").access(druidRule)
         指定了访问druid监控view的规则

    2,GoodsController.java

    @Controller
    @RequestMapping("/goods")
    public class GoodsController {
    
        @Resource
        private GoodsMapper goodsMapper;
    
        //商品详情 参数:商品id
        @GetMapping("/goodsinfo")
        @ResponseBody
        public Goods goodsInfo(@RequestParam(value="goodsid",required = true,defaultValue = "0") Long goodsId) {
            Goods goods = goodsMapper.selectOneGoods(goodsId);
            return goods;
        }
    
        //打印当前登录用户的session
        @GetMapping("/session")
        @ResponseBody
        public String session() {
            HttpSession session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
            Enumeration e   =   session.getAttributeNames();
            String s = "";
            while( e.hasMoreElements())   {
                String sessionName=(String)e.nextElement();
                s += "name="+sessionName+";<br/>";
                s += "value="+session.getAttribute(sessionName)+";";
            }
            return s;
        }
    }

    3,GoodsMapper.java,GoodsMapper.xml,Goods.java等用来演示通过druid访问数据源,不再贴出,

       大家可访问github.com查看

    五,效果测试

    1,使用无权限的用户登录后访问

    用lhduser登录

    session信息中可以看到授权的角色是:ROLE_USER 

    访问druid:

     因为没有权限,我们看到了报错信息

    2,使用有权限的用户登录后访问

     用lhdadmin登录,查看session:

     查看druid,先用配置的账号root登录

     可以正常访问:

    3,从未授权的ip访问:注意替换成自己应用所在的ip

    http://192.168.3.182:8080/druid

    用有权限的账号lhdadmin登录,

    返回:

     可见既使有权限访问,但如果ip未加入白名单也会报错

    六,查看spring boot的版本

      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.3.3.RELEASE)
  • 相关阅读:
    以前给工大软件学院作得首页
    rinruby
    螃蟹为什么煮熟后会变红?
    关于R中利用apply、tapply、lapply、sapply、mapply、table
    hp laserjet 1020驱动 for windows
    关于睡觉巻起来姿势
    王强英語
    进程的前后台切换
    研究生=烟酒生
    计算矩阵乘法的网页工具
  • 原文地址:https://www.cnblogs.com/architectforest/p/13564473.html
Copyright © 2011-2022 走看看