【发布时间】:2019-12-10 00:59:03
【问题描述】:
我创建了一个 Oracle PL/SQL 包,我想防止它在生产环境或特定数据库上执行,这可能很危险。事实上,事实证明我拥有管理员权限,并且可能会无意中在生产环境中编译开发包。
我尝试使用类似于以下内容的方式检查包正文中的上下文:
create or replace package body my_test_package is
context varchar2(64);
function get_context return varchar2 is
begin
-- return context: DEV or PROD
...
end;
-- list of other functions & procedures ....
begin
if context = 'PROD' then
dbms_standard.raise_application_error(-20001, 'production context, prevent execution of this package');
end if;
end;
但是,我知道这是不好的解决方案,因为初始化时间只发生一次,正如Oracle documentation 所述:
包的初始化部分只起次要作用,因为与子程序不同,包不能被调用或传递参数。因此,包的初始化部分只运行一次,即您第一次引用该包时。
因此,这意味着将执行第一个过程调用之后的所有后续过程调用,即使在生产环境中也是如此。例如:
-- production environment
begin
my_test_package.dangerous_procedure();
exception when others then
dbms_output.put_line('bypass context exception');
end;
my_test_package.dangerous_procedure(); ---> EXECUTED IN PROD :(
是否有一种常见的习惯用法或已知的方法来防止包在特定环境中执行? (例如,不必在包的每个过程/函数中复制相同的代码,以检查它是否有权执行)。
谢谢
【问题讨论】:
-
如果包中的程序永远不应该在特定环境中执行,为什么包需要存在于那个环境中?如果包需要存在于该环境中,为什么有人需要对包进行
execute访问?如果你真的希望包存在于你不希望它被执行的环境中,并且你真的想授予用户执行包中他们不应该执行的方法的权限,包中的每个方法都可以运行check_context函数如果环境是您要避免的环境,则会引发错误。 -
@JustinCave 我想到了你的建议,例如
check_context函数,但这意味着在包中的每个函数/过程中大量复制同一段代码,对吗?恕我直言,这不是一个好方法。 /更新了我的问题 -
如果您希望包存在并且您希望用户有权执行这些方法并且您希望这些方法在生产中做一些不同的事情,您需要更改所有公共的代码方法。如果您不喜欢在每个公共方法中调用
check_context函数,您使用的是最新版本的 Oracle,并且您愿意放宽跨环境权限相同的约束,您可能会使用基于代码的访问控制,并且只授予包在某些环境中执行任何危险任务的权限。但这似乎是迂回的 -
我不认为问题出在程序上,而是“可能无意中在生产环境中编译开发包”;对删除语句进行重大更改怎么样?无论如何,对于程序 2 选项浮现在脑海中。 Prod 中的特殊用户,可能“无意中在生产环境中编译开发包”;删除或截断的更新版本怎么样?无论如何,对于程序,我想到了 2 种方法:生产中的特殊用户和 conditional compilation
-
生产环境中的第一个设置具有管理员权限的特定用户并从所有其他用户中删除这些用户。不要在开发中创建此用户。至于条件编译,只需放置条件语句,除非存在特定的外部条件,否则它不会编译。使用一个或两个。
标签: oracle plsql permissions package