我们可以使用 Oracle Audit 函数来记录用户登录信息,但是如果开放了 Audit 函数将会使 Oracle 性能下降,甚至导致 Oracle 崩溃。那我们如何才能记录用户登录信息呢?其实我们可以通过建立触发器的方式来实现。方法如下:
1. 用 sys 用户登录 Oracle
2. 创建记录用户登录信息的表
CREATE TABLE LOG$INFORMATION
(
ID NUMBER(10),
USERNAME VARCHAR2(30),
LOGINTIME DATE,
TERMINAL VARCHAR2(50),
IPADRESS VARCHAR2(20),
OSUSER VARCHAR2(30),
MACHINE VARCHAR2(64),
PROGRAM VARCHAR2(64),
SID NUMBER,
SERIAL# NUMBER,
AUSID NUMBER
)
/
3. 创建一个 Sequence,作为登录信息的主键
CREATE SEQUENCE LOGIN_SEQ
minvalue 1
maxvalue 9999999999
start with 1
increment by 1
cache 20
/
4. 创建触发器,记录用户登录信息
CREATE OR REPLACE TRIGGER LOGIN_RECORD_TR
AFTER logon ON DATABASE
DECLARE
mtSession v$session%ROWTYPE;
CURSOR cSession(iiQuerySid IN NUMBER) IS
SELECT * FROM v$session
WHERE audsid = iiQuerySid;
BEGIN
OPEN cSession(userenv('SESSIONID'));
FETCH cSession INTO mtSession;
IF cSession%FOUND AND SYS_CONTEXT ('USERENV','IP_ADDRESS') IS NOT NULL THEN
INSERT INTO log$information(
id,
username,
logintime,
terminal,
ipadress,
osuser,
machine,
program,
sid,
serial#,
ausid
) VALUES(
login_seq.nextval,
USER,
SYSDATE,
mtSession.Terminal,
SYS_CONTEXT ('USERENV','IP_ADDRESS'),
mtSession.Osuser,
mtSession.Machine,
mtSession.Program,
mtSession.Sid,
mtSession.Serial#,
userenv('SESSIONID')
);
END IF;
CLOSE cSession;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
/
5. 将 SYS.LOG$INFORMATION 授权给需要查看登录记录的用户
Grant select on SYS.LOG$INFORMATION to XXX