oracle - 触发器执行期间跳过错误

标签 oracle oracle11g triggers

我在数据库事件 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 错误。

  1. 当用户成功登录数据库时,我发现数据库生成了如上的警报日志:
> 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;
    /
    

    警告

    由于以下原因,请务必谨慎使用此解决方案:

    1. 您绝对不想遇到阻止所有管理员登录的情况。
    2. ORA-600 错误是生成跟踪文件的资源密集型错误。并且您的数据库可能会受到监控以自动报告此类错误。此解决方案可能会向 DBA 发送垃圾邮件。在最坏的情况下,如果自动化系统触发此错误一千次,您的操作系统可能会在意想不到的地方增长并造成拒绝服务攻击。在实现此触发器之前与您的 DBA 讨论。
    3. HOST 变量可能会被欺骗,因为 Oracle 必须依赖第 3 方数据库连接器来提供此信息。根据您的 JDBC 软件,应用程序可能会更改其主机名。实际上,没有多少人会这样做,但欺骗的能力意味着您的解决方案并不是 100% 防弹。

    我以前使用过这样的代码,它可以工作并且很有用。但您应该意识到这些限制,并使用更好的安全机制(如果有)。

    关于oracle - 触发器执行期间跳过错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77387060/

    相关文章:

    oracle - 如何将图像作为 BLOB 插入 Oracle 数据库

    linux - 如何将阿拉伯语数据导入oracle数据库?

    oracle - 安装的是哪个版本的oracle

    mysql - SQL 触发器 : Create row if row doesn't exist

    select - 选择后触发

    WPF触发器不为空

    SQL WHERE xx IN ('qq' , 'ww' ...) 性能 - 更多的值(value),更少的时间?

    sql - 是否可以在 Oracle 中将表名作为参数传递?

    sql - 更新给定值的 Oracle XMLType 列内容

    java - 无法将数组(BINARY_DOUBLE)从 Java 传递到 Oracle 存储过程?