我在数据库事件 LOGON 上创建了一个触发器,以避免未经许可的人错误地登录数据库。当主机名以C开头时,需要拒绝连接。
CREATE OR REPLACE TRIGGER "SYS"."LOGIN_RJ" AFTER LOGON ON DATABASE
DECLARE
HOST_NAME VARCHAR2(128):=SYS_CONTEXT('USERENV','HOST');
BEGIN
if (HOST_NAME like 'C%') then
raise_application_error(-20000,'host login denied');
end if;
END;
这对于大多数用户帐户很有用,但特定用户仍然可以登录数据库而不会出现任何 ORA 错误。
- 当用户成功登录数据库时,我发现数据库生成了如上的警报日志:
> Skipped error 604 during the execution of SYS.LOGIN_RJ
>
> dbkedDefDump(): Starting a non-incident diagnostic dump (flags=0x0, level=0, mask=0x0)
> Error Stack Dump -----
> ORA-00604: error occurred at recursive SQL level 1
> ORA-20000: host login denied
> ORA-06512: at line 6
- 我尝试授予/撤销角色,发现DBA或IMP_FULL_DATABASE角色会影响上述触发器。当用户被授予 IMP_FULL_DATABASE 角色时,触发器不会引发应用程序错误。
是否有其他方法可以限制用户登录而不撤销角色权限(IMP_FULL_DATABASE或DBA)?
最佳答案
可以通过在登录触发器中引发 ORA-600 错误来阻止管理帐户登录 Oracle 数据库:
CREATE OR REPLACE TRIGGER SYS.LOGIN_RJ AFTER LOGON ON DATABASE
DECLARE
--Only an ORA-600 error can stop logons for users with either
--"ADMINISTER DATABASE TRIGGER" or "ALTER ANY TRIGGER".
--The ORA-600 also generates an alert log entry and may warn an admin.
INTERNAL_EXCEPTION EXCEPTION;
PRAGMA EXCEPTION_INIT( INTERNAL_EXCEPTION, -600 );
HOST_NAME VARCHAR2(128):= SYS_CONTEXT('USERENV','HOST');
BEGIN
IF HOST_NAME LIKE 'C%' THEN
RAISE INTERNAL_EXCEPTION;
END IF;
END;
/
警告
由于以下原因,请务必谨慎使用此解决方案:
- 您绝对不想遇到阻止所有管理员登录的情况。
- ORA-600 错误是生成跟踪文件的资源密集型错误。并且您的数据库可能会受到监控以自动报告此类错误。此解决方案可能会向 DBA 发送垃圾邮件。在最坏的情况下,如果自动化系统触发此错误一千次,您的操作系统可能会在意想不到的地方增长并造成拒绝服务攻击。在实现此触发器之前与您的 DBA 讨论。
- HOST 变量可能会被欺骗,因为 Oracle 必须依赖第 3 方数据库连接器来提供此信息。根据您的 JDBC 软件,应用程序可能会更改其主机名。实际上,没有多少人会这样做,但欺骗的能力意味着您的解决方案并不是 100% 防弹。
我以前使用过这样的代码,它可以工作并且很有用。但您应该意识到这些限制,并使用更好的安全机制(如果有)。
关于oracle - 触发器执行期间跳过错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77387060/