我正试图跟踪一个失败的用户登录到Oracle数据库进行监视的目的。计划是在数据库登录时使用触发器。表已创建,触发器已成功与表关联。表CREATE语句和TRIGGER成功。当检查表值时,oracle不返回任何记录。我怎么能做到这一点?
--create table
CREATE TABLE myschema.errors(
user_name VARCHAR2(30) NOT NULL ENABLE,
error_code VARCHAR2(50) NOT NULL ENABLE,
error_message VARCHAR2(50) NOT NULL ENABLE,
error_time timestamp)
TABLESPACE "USERS";
--create application context
CREATE CONTEXT myschema6_ctx USING myschema.myschema6_pkg;
--create package body
CREATE OR REPLACE PACKAGE BODY myschema.myschema6_pkg
IS
c_context CONSTANT VARCHAR2(30) := 'myschema6_ctx';
username VARCHAR2(30);
My_USER VARCHAR2(30);
PROCEDURE set_contexts IS
BEGIN
SELECT SYS_CONTEXT ('USERENV', 'SESSION_USER') into username FROM DUAL;
SELECT SYS_CONTEXT ('USERENV', 'OS_USER') into My_USER FROM DUAL;
DBMS_SESSION.SET_CONTEXT ( c_context, username, My_USER);
END;
END myschema6_pkg;
/
--create trigger
CREATE OR REPLACE TRIGGER myschema6_ctx_trig AFTER LOGON ON DATABASE
DECLARE
My_USER VARCHAR2(30);
v_code VARCHAR2(30);
v_errm VARCHAR2(30);
BEGIN
myschema.myschema6_pkg.set_contexts;
SELECT SYS_CONTEXT ('USERENV', 'OS_USER') into My_USER FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
v_code := SQLCODE;
v_errm := SUBSTR(SQLERRM, 1 , 64);
-- to insert information about errors.
INSERT INTO myschema.errors(user_name,error_code,error_message,error_time)
VALUES(My_USER,v_code,v_errm, SYSTIMESTAMP);
END;
/
1条答案
按热度按时间zvms9eto1#
不能使用“
AFTER LOGON ON DATABASE
“触发器捕获登录失败。登录失败永远不会成功登录,因此永远不会执行此类触发器。但是,您可以使用“
AFTER SERVERERROR ON DATABASE
“触发器捕获登录失败,每当向调用客户端引发ORA异常时,就会触发该触发器,这将包括登录时的任何错误消息(无效密码、帐户锁定等)。在触发器中,查看server_error(1)
并主要查找28000
、1017
和1005
的值(它们是正的,而不是负的)。请注意,对于登录失败,v$session
中的USERNAME
将是NULL
。您必须通过查看SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY')
来获取预期的用户名。此外,不需要使用包或设置上下文。您可以使用标准的
SYS_CONTEXT('USERENV',...)
调用或通过使用SID点击像v$session
这样的V$视图来访问触发器中所需的所有内容。最后,在任何用于写入日志的触发器中,您都希望使其成为一个自治事务并包含一个COMMIT:但是,为了简单起见,我建议您首先尝试Oracle的标准登录审计。如果它被启用,只需查询
DBA_AUDIT_TRAIL
登录失败:或者,如果使用统一审核:
只有当您确实需要审计无法提供的有关客户端的丰富信息时,才使用系统错误触发器。