本文件记录了为修复登录和配置问题而对项目进行的所有修改。
web/WEB-INF/web.xml*.do、*.jsp 和 /reportServlet 的 XSS 过滤器映射 (SecurityFilter)。SecurityFilter 因 SECURITY_HTTPREFERER 不匹配而报 403 错误,即使配置了白名单也依然存在问题。在开发/测试环境中禁用它可确保登录流程顺畅。init_test_data.sqlAA10 表的 DELETE 语句,使用 AAA100 和 ITEMCODE 代替 AAZ093。FW_OPERATOR、FW_OPERATOR2RIGHT、FW_RIGHT、FW_OPERATEUNIT、FW_SYSORG 表的 DELETE 语句,以防止主键冲突。FW_OPERATOR 的插入语句:
admin: 密码重置为 admin (MD5: 21232f297a57a5a743894a0e4a801fc3)。test: 密码重置为 test (明文, PWENCRYPT='0')。FW_OPERATOR 的 DELETE 逻辑,同时根据 LOGINID 和 OPERID 删除。ID 为 1, 2, 3 的 FW_OPERATOR2RIGHT 记录的语句。AA01 的 DELETE 逻辑,根据 AAA001 (包含 CHECKIMAGE_SB) 以及 AAZ499 ID 范围 (3000-3008) 进行删除。AA01 表中增加了多条 SECURITY_HTTPREFERER 配置,以支持多种 Referer 格式。CHECKIMAGE_SB = '0' 配置以禁用登录验证码。UK_AAA100_ITEMCODE 的唯一约束冲突。web/jsp/framework/security/loginsb_i.jspRememberMe 为 RememberMe_ignored 以及 IMAGCHECK 为 IMAGCHECK_ignored。根据用户要求,此修改已撤回。RememberMe (boolean/int) 和 IMAGCHECK (string/int) 的特定类型,Struts2 的 ConversionErrorInterceptor 异常可能会再次出现。init_test_data.sql (最新更新)admin, test, admin_123456) 设置为使用明文密码。PWENCRYPT 设置为 '0'。UNSAFE_VALIDATEFORM 配置为 NEVER_MATCH_THIS_TOKEN,以防止配置为空时导致客户端验证错误。LOGIN_ENCRYPT 配置为 0,以匹配明文密码设置。LOGIN_TIP 配置为空字符串。DELETE FROM ZJRS_YWXT.FW_LOG4EXCEPTION 和 DELETE FROM ZJRS_YWXT.FW_LOG4LOGIN 语句。UNSAFE_VALIDATEFORM 为空时发生(JS split 结果为 [""],会匹配所有内容)。ORA-00001: unique constraint (ZJRS_YWXT.PK_FW_LOG4EXCEPTION_ID) violated 错误。系统尝试记录异常时,序列 SEQ_FW_LOG4EXCEPTION 生成的 ID 与表中现有数据冲突。清理该表可临时解决此问题,并允许查看实际触发异常的根本原因。web/jsp/sysmngr/web/authmngr/right_left.jsp 和 right_auth.jspLOCATE 函数替换为 Oracle 的 INSTR 函数。LOCATE 是 MySQL 函数,Oracle 不支持,导致 ORA-00904 错误。LOCATE(B.RIGHTID,A.RIGHTID) = 1 -> INSTR(A.RIGHTID, B.RIGHTID) = 1LOCATE(BAE001,'"+orgCode+"') = 1 -> INSTR('"+orgCode+"', BAE001) = 1LOCATE(substr, str) 参数顺序与 INSTR(str, substr) 相反。init_test_data.sql (兼容性函数)LOCATE 和 f_length 自定义函数的创建语句。f_length(TREEKEY))使用了 Oracle 不支持的函数,且源码难以定位或修改。ORA-00904 错误,在数据库层面实现了这两个函数的兼容版本:
LOCATE: 封装 INSTR。f_length: 封装 LENGTH。web/WEB-INF/web.xml (新增过滤器)AjaxEncodingFilter 过滤器配置。src/cn/sinobest/sysmngr/comm/filter/AjaxEncodingFilter.javaajaxAdapter.do 接口返回的 JSON 数据中文乱码问题。UTF-8。src/cn/sinobest/sysmngr/comm/filter/AjaxEncodingFilter.java (增强版)HttpServletResponseWrapper 包装响应对象。response.setCharacterEncoding("UTF-8") 可能无效,因为后续的 Action 代码(在 JAR 包中)可能会覆盖此设置(例如调用 setContentType("text/html;charset=GBK"))。setContentType 和 setCharacterEncoding 方法,拦截并忽略任何非 UTF-8 的编码设置尝试,强制确保最终响应为 UTF-8。request.setCharacterEncoding("UTF-8"),确保请求参数(POST Body)也能被正确解析。setContentType 的逻辑:不仅忽略非 UTF-8,还会尝试将 charset=GBK 替换为 charset=UTF-8。getWriter(),在获取 Writer 之前再次强制设置 Response 编码为 UTF-8。src/cn/sinobest/sysmngr/comm/filter/AjaxEncodingFilter.java (GBK 版)UTF-8 改为 GBK。ajaxAdapter.do 返回的数据被浏览器解析为 UTF-8 时出现乱码(例如 湛 显示为 տ),这表明后端实际上发送的是 GBK 编码的字节流。GBK 解码应该能正确显示中文。Tomcat 配置问题 (URIEncoding):
whereCls=...)包含中文时乱码。URIEncoding 为 ISO-8859-1(旧版)或 UTF-8(新版)。如果应用预期 UTF-8 但 Tomcat 使用 ISO-8859-1,则参数乱码。server.xml 中的 <Connector ... URIEncoding="UTF-8" />。ajaxAdapter.do 是 POST 请求,参数在 Body 中,通常由 CharacterEncodingFilter (web.xml) 处理,不受 URIEncoding 影响。代码/响应编码问题 (Content-Type):
{"title":"???"})。response.setCharacterEncoding("UTF-8"),导致服务器使用默认编码(通常是 ISO-8859-1)发送数据,而浏览器/客户端按 UTF-8 解析。TreeAction.java)显式设置编码。ajaxAdapter.do),添加过滤器 (AjaxEncodingFilter) 强制设置响应编码。loginsb_i.jsp)不安全字符验证:
var fwUnsafeValidateFormTokens = "<%=UNSAFE_VALIDATEFORM%>".split("|");UNSAFE_VALIDATEFORM 为空时,split("|") 返回 [""](包含一个空字符串的数组)。indexOf("") 对任何字符串都返回 0,导致所有输入都被误判为包含“不安全字符”,阻止登录。UNSAFE_VALIDATEFORM 为 NEVER_MATCH_THIS_TOKEN,避免空字符串匹配。密码加密逻辑:
javascript
if (isEncrypty == '1') {
var _1 = frm._1_.value;
t = stringToHex(encrypt(_1,pw));
}
isEncrypty 来自数据库配置 LOGIN_ENCRYPT。encrypt.js 进行加密。但如果后端没有对应的解密逻辑(或期望 MD5),会导致密码不匹配。admin 等账户密码已被重置为明文或简单的 MD5。为了简化调试,我们将 LOGIN_ENCRYPT 设为 '0'(不加密),并让所有账户使用明文密码。Struts2 类型转换异常 (ConversionErrorInterceptor):
RememberMe (checkbox) 和 IMAGCHECK (text) 字段。如果 Action 类(位于 JAR 包中,源码不可见)将这些字段定义为 int 或 boolean,而前端提交的是 "on" (checkbox 默认值) 或 "" (空字符串),Struts2 默认的拦截器会尝试转换类型并失败。数据库 ID 冲突 (ORA-00001):
unique constraint (ZJRS_YWXT.PK_FW_LOG4EXCEPTION_ID) violated。FW_LOG4EXCEPTION 表时,使用的序列 SEQ_FW_LOG4EXCEPTION 生成的 ID 小于表中已存在的最大 ID。DELETE FROM ZJRS_YWXT.FW_LOG4EXCEPTION 清空表数据,消除 ID 冲突,从而允许系统正常写入新的异常日志,以便我们看到真正的错误原因。前端加密 (encrypt.js):
_1_ (session 中的 des_key)。encrypt(key, password) 将密码转换为加密字符串,再通过 stringToHex 转为十六进制。LOGIN_ENCRYPT = '1' 时启用。后端验证:
FW_OPERATOR 表包含 PASSWORD 和 PWENCRYPT 字段。PWENCRYPT='1': 密码已加密(通常是 MD5)。PWENCRYPT='0': 密码为明文。PWENCRYPT 设为 '0' 且 PASSWORD 设为明文,同时前端 LOGIN_ENCRYPT 设为 '0',确保前后端均以明文传输和比对,排除加密算法不一致导致的问题。