利用數據庫視圖實現WEB查詢敏感信息接口動態脫敏

前言:mysql

利用數據庫視圖,實現web接口查詢敏感信息時動態脫敏。web

具體目標:某接口爲用戶信息查詢接口,返回敏感用戶信息(id,姓名、手機號【敏感】、身份證號【敏感】),若是web用戶爲管理員角色,則查詢後返回明文用戶信息,若是用戶爲普通用戶信息,則查詢後返回脫敏後的用戶信息。spring

具體步驟:sql

1、在mysql中新建一個用戶信息表,並添加幾條數據數據庫

2、對上表建立脫敏後的視圖,利用掩碼技術脫敏,脫敏字段爲phone和id_cardapache

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;

 

3、SpringBoot項目啓用SpringSecurity,在配置文件中,內存新建帳號的時候添加admin和normal兩個角色app

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

 

4、建立UserInfo的domain類dom

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

 

5、建立Mapper,訪問數據庫的接口,兩個查詢方法,以便按不一樣的角色區分查詢原始表仍是脫敏後的視圖ide

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

 

6、建立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

 

7、建立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

 

 8、測試驗證

一、訪問SpringBoot WEB,進入登陸頁面

 

 二、使用admin用戶登陸後,訪問查詢用戶信息接口,以下圖所示,返回的是明文用戶信息

三、使用user普通用戶登陸後訪問,以下圖所示,返回的是脫敏後的用戶信息

利用數據庫視圖技術實現動態脫敏,適用於web應用,適用於生產環境,可按用戶角色返回脫敏先後的查詢結果。可是全部敏感數據表均需生成視圖,額外佔用數據庫存儲空間;爲了實現目標,研發人員須要額外的開發工做量。

相關文章
相關標籤/搜索