Appearance
数据权限配置 ¶
TIP
更详细的内容可以查看 身份识别与访问管理 下的具体模块,有更详细的说明。
功能 ¶
- 数据字段字段加密解密,在数据库中存储AES加密后的内容,预防信息被脱裤后导致信息泄露
- 返回数据信息敏感信息脱敏,后端信息返回给前端时,对一些敏感信息进行脱敏,如密码、秘钥等,防止保密信息被流出,可以结合数据字段加密一起使用
- 数据范围权限控制,通过在线配置,实现不同的用户可以查询到不同范围的数据,更好的实现数据分级管理
- 查询字段权限控制,通过对字段配置权限码,可以实现不同的用户查询到不同的数据字段,更好的实现数据分级管理
字段加密解密 ¶
WARNING
只有通过通过MyBatis-Plus对整个对象进行保存或更新时才生效,通过Wrapper进行局部更新时会导致字段加密失败,需要手动进行加密。 解密时映射对象类需要是字段加EncryptionField
的类,否则无法识别到哪个字段是要进行解密的。 目前支持String类型的字段进行加解密
注解配置 ¶
在数据库表对应的类需要加密的字段,加上EncryptionField
注解,该字段在进行保存或更新时自动对该字段进行加密,在读取的时候,进行解密
java
@Data
@Accessors(chain = true)
@TableName("pc_alipay_config")
public class AlipayConfig {
/** 私钥 字段进行加密保存 */
@EncryptionField
private String privateKey;
/** 应用公钥证书 */
@BigField
@EncryptionField
private String appCert;
/** 支付宝公钥证书 */
@BigField
@EncryptionField
private String alipayCert;
/** 支付宝CA根证书 */
@BigField
@EncryptionField
private String alipayRootCert;
}
手动加解密 ¶
java
/**
* 加密
*/
public Object encryptValue(Object fieldValue){
if (fieldValue instanceof String){
// fieldDecryptKey AES秘钥,
AES aes = SecureUtil.aes(fieldDecryptKey.getBytes(StandardCharsets.UTF_8));
return aes.encryptBase64((String) fieldValue);
} else {
return fieldValue;
}
}
/**
* 解密
*/
public Object decryptValue(Object fieldValue){
if (fieldValue instanceof String){
AES aes = SecureUtil.aes(fieldDecryptKey.getBytes(StandardCharsets.UTF_8));
return new String(aes.decrypt(Base64.decode((String)fieldValue)),StandardCharsets.UTF_8);
}
else {
return fieldValue;
}
}
相关配置
yaml
bootx.starter.data-perm:
# 字段加密AES秘钥,需要符合AES格式
field-decrypt-key: 秘钥
敏感数据脱敏 ¶
TIP
对应前端使用方法见 数据脱敏(Vue3)
返回值序列化方式要为Jackson,否则会不生效。目前支持String类型的字段进行脱敏 在要返回给前端对象类中的字段上,添加上SensitiveInfo
注解,在数据返回前端时,字段根据设定的规则,对字段值进行脱敏
EncryptionField
参数 ¶
value
敏感信息类型,参数为SensitiveType
敏感信息脱敏类型枚举,具体类型如下CHINESE_NAME
中文名,只显示第一个汉字,其他隐藏为2个星号,比如:李**USER_ID
用户ID,userId 统一替换为 0L,PASSWORD
密码,密码的全部字符都用*代替,比如:******
ID_CARD
身份证号,只显示前六位和后两位,如370112**********1X
FIXED_PHONE
座机号,显示前四位,后两位MOBILE_PHONE
手机号,前三位,后4位,其他隐藏,比如135****2210
IP
IP地址,只显示前两段ip,如192.168.*.*
ADDRESS
地址,只显示到地区(前6位),不显示详细地址,比如:北京市海淀区****
EMAIL
电子邮件地址,邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示,比如:d**@foxmail.com
BANK_CARD
中国大陆车牌,车牌中间用*代替,如鲁A8***0
BANK_CARD
银行卡,卡号脱敏 :1101 **** **** **** 3256
CNAPS_CODE
公司开户银行联号,中间用*号代替OTHER
其他,通过front
和end
属性来决定保留前面或后面几个字符正常显示
front
保留:前面的front位数;从1开始,敏感类型为其他时可用end
保留:后面的end位数;从1开始,敏感类型为其他时可用
示例 ¶
java
@Data
@Accessors(chain = true)
@Schema(title = "用户信息")
public class UserInfoDto implements Serializable {
@Schema(description= "名称")
private String name;
@Schema(description= "密码")
@SensitiveInfo(SensitiveType.PASSWORD)
private String password;
@Schema(description= "手机号")
@SensitiveInfo(SensitiveType.MOBILE_PHONE)
private String phone;
@Schema(description= "邮箱")
@SensitiveInfo(SensitiveType.EMAIL)
private String email;
}
数据范围权限 ¶
WARNING
一个用户只能分配一种数据权限,不支持拥有多种,如果用户未被分配数据权限,默认是SELF
级别,只能查看自己的数据。在查询、更新、删除操作的时候可以应用数据范围权限, 如果是多表联查时,会以主表为准。如果未被MybatisPlus管理的表(有对应的数据实体类,并被MybatisPlus扫描到)和表中无权限字段或,会自动停用数据权限,防止出现SQL报错。
类型说明 ¶
SELF
只能查看自己的数据USER_SCOPE
可以查看指定用户的数据DEPT_SCOPE
可以查看指定部门的数据DEPT_AND_USER_SCOPE
可以查看指定部门和指定用户的数据ALL_SCOPE
可以查询全部数据BELONG_DEPT
只能查看自己部门人员的数据BELONG_DEPT_AND_SUB
可以查看自己部门及下级部门的数据
使用说明 ¶
在要进行用户数据范围权限控制的方法上添加 Permission
注解,该方法以及调用的子方法都将进行数据范围权限拦截,如果被嵌套的某些子方法不需要进行权限控制, 可以添加 NestedPermission
注解到方法或类上上来排除权限控制。
可以添加到类或者方法上,添加到类时对当前类所有方法生效,如果类和方法中都进行了添加,以方法上的为准。 放到数据实体类上时,如果
dataScope
或selectField
值为false
,将会在任何权限查询的时候停用权限控制,如果设置为true
值无任何效果
@Permission
参数 | 功能 | 备注 |
---|---|---|
dataScope | 数据范围权限 | 默认为true |
selectField | 查询字段权限 | 默认为true |
@NestedPermission
只会在
@Permission
嵌套的方法内生效,该方法需要被Spring代理到,否则不生效
参数 | 功能 | 备注 |
---|---|---|
dataScope | 数据范围权限 | 默认为false |
selectField | 查询字段权限 | 默认为false |
示例 ¶
java
/**
* 数据权限演示
*
* @author xxm
* @date 2022/2/21
*/
@Slf4j
@Service
@Permission
@RequiredArgsConstructor
public class DataPermDemoService {
private final DataPermDemoManager dataPermDemoManager;
/**
* 分页
*/
@Permission
public PageResult<DataPermDemo> page(PageParam pageParam) {
return MpUtil.convert2PageResult(dataPermDemoManager.page(pageParam));
}
/**
* 获取 单条
*/
public DataPermDemo findById(Long id) {
return dataPermDemoManager.findById(id).orElseThrow(DataNotExistException::new);
}
/**
* 更新
*/
public void update(DataPermDemo param) {
DataPermDemo dataPermDemo = dataPermDemoManager.findById(param.getId()).orElseThrow(DataNotExistException::new);
BeanUtil.copyProperties(param, dataPermDemo, CopyOptions.create().ignoreNullValue());
dataPermDemoManager.updateById(dataPermDemo);
}
/**
* 删除
*/
public void delete(Long id) {
dataPermDemoManager.findById(id).orElseThrow(DataNotExistException::new);
dataPermDemoManager.deleteById(id);
}
}
查询字段权限 ¶
TIP
通过结合@PermCode
注解实现,将@PermCode
注解加到数据库实体类或对应的字段上,在进行SQL查询时,会自动将没有权限的字段去掉,只查询拥有权限的字段。 启用和嵌套子方法使用方式同数据范围权限
类似,需要在标注@Permission
注解方法或子方法中才会生效。
使用说明 ¶
@PermCode
注解可以放在数据实体类类上或字段上,放在字段上时,会对该字段启用查询字段权限,权限码可以配置多个,用户拥有任意一个就可, 放在类上时相当于所有字段都标注了该权限码。类和字段上同时都标注了该注解,相当于该字段拥有这两个注解的权限码合集。
示例 ¶
java
public class DataPermDemo extends MpBaseEntity {
@PermCode("123")
private String name;
@PermCode("123")
private String creatorName;
@PermCode({"123","admin"})
private String remark;
}