利用數據庫視圖實現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應用,適用於生產環境,可按用戶角色返回脫敏前后的查詢結果。但是所有敏感數據表均需生成視圖,額外占用數據庫存儲空間;為了實現目標,研發人員需要額外的開發工作量。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM