zoukankan      html  css  js  c++  java
  • 利用数据库视图实现WEB查询敏感信息接口动态脱敏

    前言:

    利用数据库视图,实现web接口查询敏感信息时动态脱敏。

    具体目标:某接口为用户信息查询接口,返回敏感用户信息(id,姓名、手机号【敏感】、身份证号【敏感】),如果web用户为管理员角色,则查询后返回明文用户信息,如果用户为普通用户信息,则查询后返回脱敏后的用户信息。

    具体步骤:

    一、在mysql中新建一个用户信息表,并添加几条数据

    二、对上表创建脱敏后的视图,利用掩码技术脱敏,脱敏字段为phone和id_card

    create view  user_info_view as select id,name,concat(left(phone,3),'****',right(phone,3)) as phone,concat(left(id_card,4),'**************') as id_card from user_info;

    三、SpringBoot项目启用SpringSecurity,在配置文件中,内存新建账号的时候添加admin和normal两个角色

    package Eleven.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Bean
        public PasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder();
        }
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("123456")).roles("admin");
            auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("123456")).roles("normal");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests() // 定义哪些URL需要被保护、哪些不需要被保护
                    .antMatchers("/login").permitAll()// 设置所有人都可以访问登录页面
                    .anyRequest().authenticated()  // 任何请求,登录后可以访问
                    .and()
                    .formLogin().loginPage("/login")
            ;
    
        }
    }
    View Code

    四、创建UserInfo的domain类

    package Eleven.domain;
    
    public class UserInfo {
    
        private long id;
        private String name;
        private String phone;
        private String id_card;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public String getId_card() {
            return id_card;
        }
    
        public void setId_card(String id_card) {
            this.id_card = id_card;
        }
    }
    View Code

    五、创建Mapper,访问数据库的接口,两个查询方法,以便按不同的角色区分查询原始表还是脱敏后的视图

    package Eleven.mapper;
    
    import Eleven.domain.UserInfo;
    import org.apache.ibatis.annotations.*;
    
    
    @Mapper
    public interface UserMapper {
    
    
        //根据用户名查询,查询原始表,明文显示敏感信息
        @Select("select * from user_info where name=#{name}")
        UserInfo findByName(String name);
    
        //根据用户名查询,查询脱敏后的视图表,脱敏显示敏感信息
        @Select("select * from user_info_view where name=#{name}")
        UserInfo findByNameSec(String name);
    }
    View Code

    六、创建Service 和Impl文件

    package Eleven.service;
    
    
    import Eleven.domain.UserInfo;
    
    public interface UserService {
        
        public UserInfo find(String name);
    
        public UserInfo findSec(String name);
    
    }
    View Code
    package Eleven.impl;
    
    import Eleven.domain.UserInfo;
    import Eleven.mapper.UserMapper;
    import Eleven.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserMapper userMapper;
    
    
        @Override
        public  UserInfo find(String name){
            return userMapper.findByName(name);
        }
    
        public  UserInfo findSec(String name){
            return userMapper.findByNameSec(name);
        }
    }
    View Code

    七、创建controller文件,其中Get请求中,获取登录用户的角色,不同的角色调用Service中不同的函数,最终admin用户在数据库原始表中执行SQL查询,普通用户在脱敏后的视图中执行SQL查询

    package Eleven.controller;
    
    import Eleven.domain.User;
    import Eleven.domain.UserInfo;
    import Eleven.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
        @Autowired
        private UserService userService;
    
        @GetMapping("/findByName")
        public Object findByName(String name){
            /**
             * 获取登录用户的角色,不同角色调用Service中不同的函数,最终执行不同的Sql查询
             */
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (auth.getAuthorities().toString().equals("[ROLE_admin]")){
                UserInfo userInfo = userService.find(name);
                return userInfo;
            }
             else if (auth.getAuthorities().toString().equals("[ROLE_normal]")){
                UserInfo userInfo = userService.findSec(name);
                return userInfo;
            }
             else {
                 return auth.getAuthorities().toString();
            }
    
        }
    
    }
    View Code

     八、测试验证

    1、访问SpringBoot WEB,进入登录页面

     2、使用admin用户登录后,访问查询用户信息接口,如下图所示,返回的是明文用户信息

    3、使用user普通用户登录后访问,如下图所示,返回的是脱敏后的用户信息

    利用数据库视图技术实现动态脱敏,适用于web应用,适用于生产环境,可按用户角色返回脱敏前后的查询结果。但是所有敏感数据表均需生成视图,额外占用数据库存储空间;为了实现目标,研发人员需要额外的开发工作量。

  • 相关阅读:
    【JZOJ4244】yi【贪心】
    【JZOJ4244】yi【贪心】
    基本赋值运算符
    自增自减运算符
    字符串的+操作
    算术运算符
    数据类型转换
    键盘输入使用
    基本数据类型长度
    变量
  • 原文地址:https://www.cnblogs.com/Eleven-Liu/p/11234324.html
Copyright © 2011-2022 走看看