在Oracle数据库的默认配置中,密码策略仅支持简单的复杂度校验,无法满足企业对于密码安全性、合规性的特殊要求,自定义密码效验程序可以让管理员根据自身需求灵活定义校验规则,从根源上提升用户账户的安全性。

自定义密码效验程序的核心原理
Oracle数据库支持通过配置PASSWORD_VERIFY_FUNCTION参数来指定自定义的密码校验函数,当用户创建或修改密码时,系统会自动调用该函数执行校验逻辑,若函数返回成功则允许密码修改,若返回失败则提示错误并拒绝修改。
自定义的校验函数需要满足Oracle的规范要求:必须是PL/SQL函数,接收用户名和密码作为参数,返回布尔类型的结果,同时需要有权限被数据库调用。
编写自定义密码效验函数
以下是一个满足常见安全要求的校验函数示例,规则包括:密码长度不小于8位、必须包含大小写字母和数字、不能与用户名相同、不能包含连续3个相同字符。
CREATE OR REPLACE FUNCTION custom_pwd_verify (
username VARCHAR2,
password VARCHAR2,
old_password VARCHAR2
) RETURN BOOLEAN IS
v_has_upper NUMBER := 0;
v_has_lower NUMBER := 0;
v_has_digit NUMBER := 0;
v_len NUMBER;
BEGIN
-- 检查密码长度
v_len := LENGTH(password);
IF v_len < 8 THEN
RAISE_APPLICATION_ERROR(-20001, '密码长度不能小于8位');
END IF;
-- 检查密码不能与用户名相同
IF UPPER(password) = UPPER(username) THEN
RAISE_APPLICATION_ERROR(-20002, '密码不能与用户名相同');
END IF;
-- 检查是否包含大写字母、小写字母、数字
FOR i IN 1..v_len LOOP
IF SUBSTR(password, i, 1) BETWEEN 'A' AND 'Z' THEN
v_has_upper := 1;
ELSIF SUBSTR(password, i, 1) BETWEEN 'a' AND 'z' THEN
v_has_lower := 1;
ELSIF SUBSTR(password, i, 1) BETWEEN '0' AND '9' THEN
v_has_digit := 1;
END IF;
END LOOP;
IF v_has_upper = 0 OR v_has_lower = 0 OR v_has_digit = 0 THEN
RAISE_APPLICATION_ERROR(-20003, '密码必须包含大小写字母和数字');
END IF;
-- 检查是否包含连续3个相同字符
FOR i IN 1..v_len - 2 LOOP
IF SUBSTR(password, i, 1) = SUBSTR(password, i+1, 1)
AND SUBSTR(password, i, 1) = SUBSTR(password, i+2, 1) THEN
RAISE_APPLICATION_ERROR(-20004, '密码不能包含连续3个相同字符');
END IF;
END LOOP;
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
RETURN FALSE;
END custom_pwd_verify;
/配置数据库启用自定义效验程序
函数创建完成后,需要将其关联到对应的用户配置文件(Profile),才能让规则生效,具体步骤如下:
1. 授予函数执行权限
需要将函数的执行权限授予给公共角色,确保数据库可以正常调用该函数:
GRANT EXECUTE ON custom_pwd_verify TO PUBLIC;
2. 修改Profile的校验参数
可以修改默认的DEFAULT配置文件,也可以创建新的配置文件,将PASSWORD_VERIFY_FUNCTION设置为自定义的函数名:
-- 修改DEFAULT配置文件
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION custom_pwd_verify;
-- 如果需要创建新的配置文件
CREATE PROFILE custom_profile LIMIT
PASSWORD_VERIFY_FUNCTION custom_pwd_verify
PASSWORD_LIFE_TIME 90
PASSWORD_REUSE_TIME 180;3. 将用户关联到对应Profile
如果使用了新的配置文件,需要将目标用户关联到该Profile:
ALTER USER test_user PROFILE custom_profile;
校验规则测试
配置完成后可以测试密码修改是否符合预期,以下是几种常见场景的测试结果:
| 测试场景 | 密码内容 | 预期结果 |
|---|---|---|
| 长度不足 | Abc123 | 修改失败,提示密码长度不能小于8位 |
| 与用户名相同 | test_user | 修改失败,提示密码不能与用户名相同 |
| 缺少数字 | Abcdefgh | 修改失败,提示密码必须包含大小写字母和数字 |
| 符合规则 | Abc12345 | 修改成功 |
常见问题排查
- 如果修改密码时提示函数不存在,需要检查函数是否正确创建,以及是否授予了PUBLIC执行权限。
- 如果校验规则不生效,需要检查用户的Profile是否正确关联了自定义校验函数,可以通过
DBA_PROFILES视图查询配置。 - 自定义函数中如果需要添加更多规则,比如禁止密码包含字典词汇,可以在函数中引入外部字典表进行校验。