1 需求
有些情況下,有些表的特定列含有敏感數(shù)據(jù)(如用戶信息表中,用戶手機(jī)號),自然,我們只想讓“管理員”用戶看到這些敏感數(shù)據(jù),其他用戶我們希望其看到“處理后的”—— 脫敏的數(shù)據(jù)。
2 實(shí)現(xiàn)方案介紹
方案1: 使用pg匿名化插件postgresql_anonymizer;
方案2: 使用視圖進(jìn)行脫敏;
2.1 方案1: 使用pg匿名化插件postgresql_anonymizer
(示例來自插件官方文檔)
-- 修改配置文件: shared_preload_libraries = 'pg_stat_statements, anon'
-- 1. 創(chuàng)建并激活插件
CREATE EXTENSION IF NOT EXISTS anon CASCADE;
SELECT anon.mask_init();
-- 2.聲明屏蔽的用戶
CREATE ROLE skynet;
COMMENT ON ROLE skynet IS 'MASKED';
-- 3.聲明屏蔽規(guī)則
COMMENT ON COLUMN people.name IS 'MASKED WITH FUNCTION anon.random_last_name()';
COMMENT ON COLUMN people.phone IS 'MASKED WITH FUNCTION anon.partial(phone,2,$$******$$,2)';
-- 4. 查詢屏蔽敏感信息的用戶
\! psql test -U skynet -c 'SELECT * FROM people;'
id | name | phone
-----+----------+------------
T800 | n3xtchen | 13******11
2.2 方案2: 使用視圖進(jìn)行脫敏
(示例來自本地開發(fā)環(huán)境)
-- 1. 創(chuàng)建測試用戶
create user root;
create user normal_user;
-- 2. 切換到root建表 & 視圖
set role root;
create table user_phone_number(id int, user_name name, phone_number name);
insert into user_phone_number values(1, '張三', '12345678');
insert into user_phone_number values(1, '李四', '56781234');
create or replace view member_phone_number as
SELECT
S.id,
S.user_name,
substring(S.phone_number, 1,1) || '******' ||substring(S.phone_number, 8,8) as phone_number
FROM user_phone_number AS S;
-- 3. 回收表的權(quán)限,授予普通用戶view權(quán)限
revoke all on user_phone_number from public;
grant all on member_phone_number to normal_user;
-- 4. 使用普通用戶測試
reset role;
set role normal_user;
select * from user_phone_number;
select * from member_phone_number;
結(jié)果如下:
3 優(yōu)缺點(diǎn)比較
總的來看,喜歡“偷懶”、喜歡嘗鮮的話,可以使用 postgresql_anonymizer 插件;但如果追求穩(wěn)定,建議使用視圖來實(shí)現(xiàn)。
4 參考
1.PostgreSQL: 匿名化(Anonymizer)工具 官網(wǎng):https://labs.dalibo.com/postgresql_anonymizer
2.PostgreSQL: 匿名化(Anonymizer)工具 官方文檔: https://postgresql-anonymizer.readthedocs.io/en/stable/