CREATE OR REPLACE TRIGGER SYS.LOG_SYS_CONNECTIONS
AFTER LOGON
ON DATABASE
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF USER != 'SYS' OR SYS_CONTEXT('USERENV','SESSIONID') IN (0,4294967295) -- background processes
THEN
NULL;
ELSE
EXECUTE IMMEDIATE '
INSERT INTO sys.sys_connection_log
(s.username,
s.client_os_user,
s.process,
s.machine,
s.program,
s.service_name,
s.sid,
s.serial#,
s.logon_time,
cix.authentication_type,
cix.client_charset,
cix.client_version,
cix.client_driver,
SYS_CONTEXT(''USERENV'',''PROXY_USER'') proxy_user,
SYS_CONTEXT(''USERENV'',''DBLINK_INFO'') dblink_info,
SYS_CONTEXT(''USERENV'',''AUTHENTICATED_IDENTITY'') authenticated_identity,
SYS_CONTEXT(''USERENV'',''AUTHENTICATION_METHOD'') authentication_method
FROM v$session s
OUTER APPLY (SELECT MAX(NULLIF(authentication_type,''Unknown'')) authentication_type,
MAX(NULLIF(client_charset,''Unknown'')) client_charset,
MAX(NULLIF(client_version,''Unknown'')) client_version,
MAX(NULLIF(client_driver,''Unknown'')) client_driver
FROM v$session_connect_info ci
WHERE ci.sid = s.sid
AND ci.serial# = s.serial#) cix
WHERE sid = SYS_CONTEXT(''USERENV'',''SID'')
';
COMMIT;
END IF;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
/
1条答案
按热度按时间6za6bjd01#
当然。虽然标准的审计会为你提供一些信息,但它是相当有限的。您需要一个登录触发器来捕获丰富的会话信息并将其记入日志。下面是一个例子:
字符串
显然,您需要创建日志记录表(在我的示例中为
sys_connection_log
)。几点注意事项:1.为了防止后台进程出现问题,我们检查audsid(
SYS_CONTEXT('USERENV','SESSIONID')
返回v$session.audsid
,对于后台进程,它是0或0,4294967295),如果它是后台进程,则不执行任何操作。只是格外小心。我们可以简单地查询v$session
并查看TYPE
,但这允许我们甚至不需要一个查询就退出。1.插入本身被 Package 在一个动态
EXECUTE IMMEDIATE
块中。虽然这不是绝对必要的,因为SQL没有任何动态性,但这是一种安全措施。如果您的SQL有任何问题,或者如果您的日志记录表被删除,或者任何可能导致SQL解析失败的情况,您都不希望触发器变得无效,并可能阻止登录的发生。这样,任何解析失败都会在触发器中引发一个异常,然后我们处理它,什么也不做(WHEN OTHERS THEN NULL
)。1.我们使用一个自治事务,这样就可以提交insert。这对于登录触发器可能不是必需的,因为Oracle可能仍然有一个隐式提交,它将跟随触发器,因为它是一个系统事件,但为了确保,我们希望确保我们的记录被保留。在没有
PRAGMA AUTONOMOUS_TRANSACTION
的触发器中不能执行提交。