我正在尝试构建一个 Oracle 11g 登录触发器,该触发器将特定用户的访问权限限制为已知的应用程序列表。例如,用户SCOTT
只能连接MYAPP.EXE
.
我相信我有正确的触发器和逻辑,但我遇到的问题是RAISE_APPLICATION_ERROR();
不会终止会话。触发器已启用,我尝试授予ADMINISTER DATABASE TRIGGER
权限,但我仍然缺少一些东西。
基于this example,这是我到目前为止的触发器(由同一用户拥有):
CREATE OR REPLACE TRIGGER global_logon_trg AFTER logon ON DATABASE
DECLARE
p_session_user varchar2(64);
p_module varchar2(64);
BEGIN
SELECT UPPER(SYS_CONTEXT('USERENV', 'SESSION_USER')) INTO p_session_user FROM DUAL;
SELECT UPPER(SYS_CONTEXT('USERENV', 'MODULE')) INTO p_module FROM DUAL;
DBMS_SESSION.SET_IDENTIFIER(p_session_user || '-' || p_module);
IF ((p_session_user = 'SCOTT') AND (p_module IN ('MYAPP.EXE'))) THEN
DBMS_SESSION.SET_IDENTIFIER('about to raise app_error..');
RAISE_APPLICATION_ERROR(-20003,'You are not allowed to connect to the database');
END IF;
END;
/
但是SCOTT
使用 SQL*Plus 登录仍然有效。如果我随后查询v$session
,则使用以下查询:
select username, client_identifier
from v$session
where username not in ('SYSMAN', 'DBSNMP');
我得到以下结果..
USERNAME CLIENT_IDENTIFIER
------------------ -----------------------------------
SCOTT about to raise app_error..
我错过了什么? 这是特权问题、触发代码问题还是Oracle 错误问题?还是有更好的方法来做我想做的事情?!(我可以完全控制数据库和它所在的服务器,如果这样更容易的话!)
我在用着Oracle Database 11g Release 11.1.0.6.0 - Production
非常感谢您的帮助和建议
安德鲁:o)
Scott 模式是否被授予 DBA 角色?从关于 Asktom 的讨论来看,似乎 DBA 组的成员无法通过 ON LOGON 触发器断开连接。
顺便说一句,您还将在该线程中看到为什么您的解决方案不是防弹的(例如
copy sqlplus.exe foo.exe
:)更新:另外,此触发器在以下情况下不起作用:
您能否检查一下触发器是否归 SCOTT 所有?
查看 TOM KYTE 的博客/问答网站asktom。可能有一个微妙的原因导致它没有像您预期的那样工作。
您在此处 和此处讨论的问题有两个示例。
另一种方法是使用仅由应用程序启用的应用程序角色和应用程序中配置的密码。
作为一名 DBA,我不想在任何情况下限制通过 SQLPLUS 访问数据库,因为这通常是您访问病态数据库的最佳途径。并将其置于全球触发器中。没办法,伙计!