利用数据库视图实现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")
; }
}
四、创建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;
}
}
五、创建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);
}
六、创建Service 和Impl文件
package Eleven.service;
import Eleven.domain.UserInfo;
public interface UserService {
public UserInfo find(String name);
public UserInfo findSec(String name);
}
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);
}
}
七、创建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();
} } }
八、测试验证
1、访问SpringBoot WEB,进入登录页面

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

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

利用数据库视图技术实现动态脱敏,适用于web应用,适用于生产环境,可按用户角色返回脱敏前后的查询结果。但是所有敏感数据表均需生成视图,额外占用数据库存储空间;为了实现目标,研发人员需要额外的开发工作量。
利用数据库视图实现WEB查询敏感信息接口动态脱敏的更多相关文章
- IdentityServer4源码解析_5_查询用户信息接口
协议简析 UserInfo接口是OAuth2.0中规定的需要认证访问的接口,可以返回认证用户的声明信息.请求UserInfo接口需要使用通行令牌.响应报文通常是json数据格式,包含了一组claim键 ...
- SPRING IN ACTION 第4版笔记-第九章Securing web applications-011-把敏感信息请求转为https(requiresChannel())
1.把包含敏感信息的请求转为https请求,则较为安全,但如何只把有需要安全的请求转为https,而不是不加分辩就把所有请求都转为https呢?可以用requiresChannel() @Overri ...
- jboss eap 6.2+ 版本中 加密datasource密码等敏感信息
默认情况下,在jboss eap 6.2+ 管理控制台创建datasource后,会在standalone.xml(独立模式)或host.xml(域模式)中以明文保存相关敏感信息. 这会给服务器留下安 ...
- jboss加密敏感信息
默认情况下,我们配置在domain.xml或host.xml文件中的信息都是明文,对一些敏感信息就显得安全性不够,可以使用jboss提供的vault机制来进行加密 下面的内容来自 http://www ...
- 如何利用GitHub搜索敏感信息
如何利用GitHub搜索敏感信息 背景: 最近总是能听到同事说在GitHub上搜到某个敏感信息,然后利用该信息成功的检测并发现某个漏洞,最后提交到对应的SRC(安全应急响应中心)换点money.顿时心 ...
- Web应用程序的敏感信息-隐藏目录和文件
Web应用程序的敏感信息-隐藏目录和文件 0x1.场景 Web应用程序根文件夹中可能存在大量隐藏信息:源代码版本系统文件夹和文件(.git,.gitignore,.svn),项目配置文件(.npmrc ...
- Web应用安全之Response Header里的敏感信息
Web应用安全之Response Header 文/玄魂 目录 Web应用安全之Response Header 前言 1.1 那些敏感的header 1.2 删除敏感的header 1.2.1 删除 ...
- Python与数据库[2] -> 关系对象映射/ORM[5] -> 利用 sqlalchemy 实现关系表查询功能
利用 sqlalchemy 实现关系表查询功能 下面的例子将完成一个通过关系表进行查询的功能,示例中的数据表均在MySQL中建立,建立过程可以使用 SQL 命令或编写 Python 适配器完成. 示例 ...
- MSSQL·查询数据库中所有索引的相关信息
阅文时长 | 0.45分钟 字数统计 | 784字符 主要内容 | 1.引言&背景 2.声明与参考资料 『MSSQL·查询数据库中所有索引的相关信息』 编写人 | SCscHero 编写时间 ...
随机推荐
- MacOS命令行打包+签名+公证+生成dmg文件
关于dmg文件是什么,和为什么要进行公证? 简单说下,dmg文件就是一个可直接在mac上安装的安装包,我自己的理解是就像windows上的exe安装包一样: 公证是将app传到苹果商店去做认证,如果不 ...
- js SetTimeout传参问题
今天写代码遇到这样一个问题,先上代码 <!--JS方法--> function textout(obj){ if(opac==60){opac=0;return;}; opac+=10; ...
- 1+x 证书 Web 前端开发初级理论考试(试卷8 )
Web前端开发初级模拟测试卷(三) 共55道题 总分:200分 形考总分:0分 一.单选题共30题,60分 1.实现向右的红色三角形,样式实现正确的是( ) A <div class=" ...
- spring cloud 2.x版本 Gateway动态路由教程
摘要 本文采用的Spring cloud为2.1.8RELEASE,version=Greenwich.SR3 本文基于前面的几篇Spring cloud Gateway文章的实现. 参考 Gatew ...
- spring cloud 2.x版本 Gateway路由网关教程
前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...
- @PostConstruct - 静态方法调用IOC容器Bean对象
需求:工具类里面引用IOC容器Bean,强迫症患者在调用工具类时喜欢用静态方法的方式而非注入的方式去调用,但是spring 不支持注解注入静态成员变量. 静态变量/类变量不是对象的属性,而是一个类的属 ...
- Java设计模式:Builder(构建器)模式
概念定义 Builder模式是一步一步创建一个复杂对象的创建型模式.该模式将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来. 应用场景 对象创建过程比较复杂,或对创建顺序或组合有依 ...
- 动态SQL屏幕条件选择(里面还有赋值的新语法)
有时候屏幕条件中使用PARAMETERS时候,如果你为空的话,会查不出数据,但是可能你的想法是不想限制而已,但是系统默认理解为了空值,这个时候,如果取判断一下条件是不是空,在SQL里决定写不写的话,会 ...
- Spring源码解析系列汇总
相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...
- xcode 运行出现的相应配置问题以及解决办法
在学习iOS开发的过程中,经常会在网上找一些demo学习,但是网上找的demo,在自己的机子上都会出各种各样的问题.下面我来整理一下,我所遇到的问题. 最近在接受一个比较老的混合开发的项目,出现了一下 ...