为了加强APEX后台密码的安全性和可靠性,对其进行弱密码改造,通过改写登录函数,判断密码可靠性,在密码不符合条件(密码长度必须大于8位小于16位,其包含数字、大小写字母与特殊符号)时跳转到密码修改页面。
判断逻辑
登录后先验证密码是否为空——为空返回false,不为空继续——判断输入密码是否与数据库加密密码相符——不符返回false,相符继续——判断是否是弱密码——否(强密码)用户登录,是(弱密码)进入密码修改页面——修改成功后返回登录界面用新密码登录。
流程图如下所示
【问题记录】页面登录时可以从P9999登录页面进入P81修改密码界面,但是想从P81修改密码界面点击进入登录界面不生效,又返回P81修改密码界面,搁这儿单人转呢?
【问题原因】密码验证方法有误,将输入密码加密后再进行密码强弱性校验这样做项IS_CHANGE_PSWD永远取到1而不是0,所以无法跳转登录页
在登录页呈现前创建分支,进行判断,如果项IS_CHANGE_PSWD为1,则说明是弱密码,
需要修改,跳转到密码修改页
详情:
加密前正常输入密码Aa123456!,加密后是jYwu7f1/liQ9N+yRyszzHA==,加密后字符长达24,超出了最大长度16,自然一直走false。
如果将输入密码Aa123456#加密再进行校验,那么无论如何都走的是false,带入到逻辑代码中就是IS_CHANGE_PSWD永远取到1,无法正常登录
反之将输入密码进行校验则会正常判断
【解决方法】将输入密码与数据库内所存密码(解密后)比较,进行密码强弱性校验时也是使用输入原密码,不要加密后校验!不要加密后校验!不要加密后校验!(重要的事说三遍)
create function apex_mpf_authentication_basic2(p_username in varchar2,p_password in varchar2)return boolean
asv_password varchar2(64);v_password_reg varchar2(64); --解密后的密码v_mobile varchar2(64);v_job_number varchar2(64);v_err_msg varchar2(2000);
beginapex_util.set_session_state('USER_NAME',p_username); --设置工号到USER_NAMEselect PASSWORD, MOBILE, JOB_NUMBERinto v_password,v_mobile,v_job_numberfrom BASIC_SYSTEM_LOGIN_USERwhere LOGIN_USER_ID in (SELECT u.LOGIN_USER_IDFROM BASIC_SYSTEM_USER_ROLE uwhere u.IS_ENABLE = 1and u.USER_ID in (select a.USER_IDfrom SHARE_BASIC_USER_V awhere a.IS_LEAVE = 0 -- 中台 EHR账户“未离职”的状态下and a.TENANT_ID = apex_util.get_session_state('USER_TENANT'))and u.TENANT_ID = apex_util.get_session_state('USER_TENANT'))and JOB_NUMBER = upper(p_username)and SYSTEM_TYPE = 'BASIC'and DEL_FLAG = 0and TENANT_ID = apex_util.get_session_state('USER_TENANT');WRITE_LOG(GET_FN_NAME(), 'debug3',p_username || p_password || apex_util.get_session_state('USER_TENANT') || v_job_number, -1, -1);if v_password is not null then --密码非空V_PASSWORD_REG := JA_UTILS_PKG.DECRYPT_DEC(v_password); --将解密的密码赋值给v_password_regif p_password <> V_PASSWORD_REG then --输入密码与数据库解密密码不符return false;else --输入密码与数据库解密密码相符-- 验证当前用户是强密码或弱密码的情况-- 8到16位,包含数字,大小写,特殊字符,不包含空格WRITE_LOG(GET_FN_NAME(), 'debug6','V_PASSWORD:'||V_PASSWORD_REG, -1, -1);IF NOT (REGEXP_LIKE(V_PASSWORD_REG, '[0-9]') ANDREGEXP_LIKE(V_PASSWORD_REG, '[a-z]') ANDREGEXP_LIKE(V_PASSWORD_REG, '[A-Z]') ANDREGEXP_LIKE(V_PASSWORD_REG, '[@#$%^&+=!.]') ANDLENGTH(V_PASSWORD_reg) BETWEEN 8 AND 16 ANDNOT REGEXP_LIKE(V_PASSWORD_REG, '\s')) THEN--弱密码的情况 IS_CHANGE_PSWD赋值1,目的:跳转修改密码页 要求用户修改密码,反之APEX_UTIL.SET_SESSION_STATE('IS_CHANGE_PSWD', 1);RETURN FALSE;ELSEAPEX_UTIL.SET_SESSION_STATE('IS_CHANGE_PSWD', 0);RETURN TRUE;END IF;end if;else --密码为空return false;end if;exceptionwhen others thenv_err_msg := sqlerrm || chr(13) || dbms_utility.format_error_backtrace;JA_WRITE_LOG(JA_UTILS_PKG.GET_FN_NAME(), 'error', v_err_msg, apex_util.get_session_state('USER_ID'),apex_util.get_session_state('USER_TENANT'), V('APP_NAME') || ':' || V('APP_ID'));return false;
end;
/
奇怪,明明都是对的,但是会报“登录身份证明无效”
原来是表BASIC_SYSTEM_USER_ROLE中未分配角色,所以找不到,其他有角色的用户带来则会正常执行。
【问题记录】同步功能到环境中,输出提示“修改失败”,查看会话,发现项值取到了,状态为“已插入”,这是怎么回事呢?
【问题原因及解决】回到对应的页面中不难发现,输出的提示是执行修改失败的语句,那就说明问题出在执行PL/SQL语句上,看一眼代码,果然,此环境下TENANT_ID = 2但是沿用了另一环境中的3了,改为对应TENANT_ID即可。
但还是修改失败,怎么回事?
回到登录函数中检验一下,
【小细节】记得在控制台开启“启用DBMSOUTPUT”,否则不会输出对应结果
代码:
declarep_password NVARCHAR2(100) := 'Aa123456#';
beginIF NOT (REGEXP_LIKE(p_password, '[0-9]') ANDREGEXP_LIKE(p_password, '[a-z]') ANDREGEXP_LIKE(p_password, '[A-Z]') ANDREGEXP_LIKE(p_password, '[@#$%^&+=!.]') ANDLENGTH(p_password) BETWEEN 8 AND 16 ANDNOT REGEXP_LIKE(p_password, '\s')) THENDBMS_OUTPUT.PUT_LINE(1);ELSE --强密码的情况DBMS_OUTPUT.PUT_LINE(0);END IF;
end;
输出结果为0,说明强密码校验通过,但是为什么修改失败呢?
破案了,原来还是TENAANT_ID的问题,改了一个,另一个没改,我的问题
【一个展示BUG】
奇怪的bug增加了,点击修改密码页面的“返回登录页”按钮,出现了一个丑丑的bug
后来找到原因了,返回登录使用的是别名,结果别名被占用,不是我想返回的登录页,将想返回的登录页别名命名过来即可。