如何通过Oracle触发器记录数据库失败登录?现有配置无数据写入
登录失败无记录的问题排查与解决
核心问题:触发器类型完全错误
你写的AFTER LOGON ON DATABASE触发器仅在用户登录成功后才会触发,登录失败时这个触发器根本不会执行,所以errors表自然没有数据。要跟踪登录失败,必须改用AFTER SERVERERROR ON DATABASE触发器,专门捕获登录失败对应的错误码(ORA-01017)。
修正后的完整实现
1. 调整错误表(可选,避免报错信息被截断)
原表的error_message仅50字符,容易截断完整的ORA错误信息,建议修改字段长度:
ALTER TABLE myschema.errors MODIFY error_message VARCHAR2(200);
2. 替换触发器为服务器错误触发器
删除原有的myschema6_ctx_trig,创建专门捕获登录失败的触发器:
CREATE OR REPLACE TRIGGER myschema.logon_fail_catcher AFTER SERVERERROR ON DATABASE DECLARE v_attempted_user VARCHAR2(30); v_err_code NUMBER; v_err_msg VARCHAR2(200); BEGIN v_err_code := SQLCODE; -- 仅处理登录失败的错误(ORA-01017对应的SQLCODE是-1017) IF v_err_code = -1017 THEN -- 登录失败时用AUTHENTICATED_USER获取尝试登录的用户名更可靠 v_attempted_user := SYS_CONTEXT('USERENV', 'AUTHENTICATED_USER'); v_err_msg := SUBSTR(SQLERRM, 1, 200); INSERT INTO myschema.errors(user_name, error_code, error_message, error_time) VALUES(v_attempted_user, v_err_code, v_err_msg, SYSTIMESTAMP); COMMIT; END IF; EXCEPTION WHEN OTHERS THEN -- 防止触发器自身报错导致登录流程异常 NULL; END; /
3. 检查权限
确保myschema用户具备以下必要权限:
GRANT ADMINISTER DATABASE TRIGGER TO myschema; GRANT CREATE SESSION TO myschema;
4. 清理冗余代码
你之前创建的myschema6_pkg包和myschema6_ctx上下文对跟踪登录失败毫无作用——登录失败时根本执行不到这些代码,可直接删除。
验证方法
用错误的用户名/密码尝试登录数据库,然后查询错误表:
SELECT * FROM myschema.errors ORDER BY error_time DESC;
此时应该能看到最新的失败登录记录。
内容的提问来源于stack exchange,提问作者Eshe
相关产品推荐
相关产品推荐

