Database 如何隐藏Oracle表?

Database 如何隐藏Oracle表?,database,oracle,schema,synonym,rights,Database,Oracle,Schema,Synonym,Rights,以下是场景(简化示例): 我有一个名为ABC的Oracle用户/模式。ABC拥有一张名为TRN的表格。客户端代码作为ABC连接到数据库,并从ABC.TRN中选择 到目前为止还不错。但是,我不希望客户端代码指定Oracle架构名称。现在我想我已经删除了客户端代码中所有引用模式的引用,但我想测试一下以确保 因此,我想创建一个名为DEF的新用户/模式,客户端将使用它连接到数据库。当客户端应用程序从ABC.TRN中选择时,它必须给出一个错误。但是,如果客户机应用程序从TRN(无架构名称)中选择,则必须返

以下是场景(简化示例):

我有一个名为ABC的Oracle用户/模式。ABC拥有一张名为TRN的表格。客户端代码作为ABC连接到数据库,并从ABC.TRN中选择

到目前为止还不错。但是,我不希望客户端代码指定Oracle架构名称。现在我想我已经删除了客户端代码中所有引用模式的引用,但我想测试一下以确保

因此,我想创建一个名为DEF的新用户/模式,客户端将使用它连接到数据库。当客户端应用程序从ABC.TRN中选择时,它必须给出一个错误。但是,如果客户机应用程序从TRN(无架构名称)中选择,则必须返回数据

有没有办法做到这一点?请注意,DEF必须与ABC位于同一数据库中,只有一个表TRN table(由ABC所有),我无法使用数据库链接

我尝试创建一个新的XYZ用户,其同义词指向ABC.TRN,并在ABC.TRN上授予其选择权限。然后我创建了一个同义词指向XYZ.TRN的DEF用户,并赋予DEF对XYZ.TRN的选择权限。这是可行的,但Oracle非常聪明,知道如果DEF有权从XYZ.TRN中进行选择,那么它也有权从ABC.TRN中进行选择,从而破坏了本练习的目的,因为我希望本例给出一个错误


交给你……

ALTER SESSION怎么样

         ALTER SESSION SET CURRENT_SCHEMA = schema
这将允许您以用户身份登录,该用户已被授予schema X拥有的表的选择权限,并执行将会话更改为schema X的SP。前端代码不会知道发生了这种情况

但是,如果前端代码指定模式X:

           select * from X.tableName
我认为这不会引起错误

也许您可以解释为什么客户端代码在使用正确的当前模式名称时收到错误很重要

是否可以创建一个新模式,转移旧模式对象的所有权,然后删除旧模式,然后使用上面的方法

请参见登录后触发器:

p.p.S.既然您详细阐述了您的要求:

。。。该表可以是使用数据库链接的同义词,也可以由多个架构中的, 每个版本都有不同的版本。应该由数据库来解析实际位置 客户端应用程序引用的对象的

如果对象的位置不在当前的_模式中,而是在其他模式中,例如,这两个模式碰巧都有名为CUSTOMER的表,那么如果表名不是如此限定的,数据库引擎就不会知道客户端应用发送给它的语句应该引用其他模式。这意味着引擎不具备一定程度的元知识,尽管它为开发人员提供了以存储过程和触发器的形式创建此类智能的工具,并授予/撤销对对象的控制权


将此智能置于后端的最佳成功机会是撤销对表和视图的所有直接权限,并要求客户端应用程序通过存储过程访问对象,因为数据库引擎本身不知道应用程序发布级别之类的事情。我看不到实现它的纯粹的声明方式。这在很大程度上必须是程序性的。您自己的后端逻辑必须负责在不同模式中相同名称的对象之间进行仲裁。也就是说,类似于登录后触发器和alterschema的特性应该对您有所帮助

你做不到。同义词只是指向其他模式对象的指针。您授予对实际对象的访问权,而不是同义词。从Oracle文档:

同义词本身并不安全。当您对同义词授予对象权限时,实际上是在对基础对象授予权限,并且同义词仅在grant语句中充当对象的别名


要做到这一点没有简单的方法

一种方法是政治性的:进行代码审查,也许可以自动搜索代码库,当人们这样做时,只需拍拍手腕

架构方法将类似于您的三架构结构,但具有微妙的扭曲:中间的架构使用视图。因此,模式ABC拥有表,并将表的权限授予模式XYZ。模式XYZ针对这些表(SELECT*,no WHERE子句)构建简单视图,并将视图的权限授予模式DEF。架构定义只能从XYZ对象中选择

当然,所有这些努力仍然不会阻止开发人员从xyz.whatever编写
SELECT*。在这种情况下,请参考我的第一个建议8-)


事实上,有一种非常邪恶的方式可以做到这一点。在面向应用程序的模式(DEF)中使用同义词,然后更改数据拥有模式(ABC)的名称


当然,只有在安装脚本完全参数化且没有硬编码模式名称的情况下,您才应该尝试这种策略。

您真的需要抛出错误吗?或者您只需要验证应用程序是否未使用完全限定名(即
ABC.TRN

假设您只对验证应用程序是否未使用完全限定名感兴趣,并且抛出错误只是您想到的通知您的机制,那么您可能可以在应用程序运行时通过查询
V$SQL
来验证代码
V$SQL
列出Oracle中共享池中的所有SQL语句。如果在应用程序运行时定期查询该表,您将看到它发出的所有SQL语句。然后可以记录使用完全限定名的任何语句

比如说

CREATE OR PROCEDURE look_for_abc_trn
AS
BEGIN
  FOR x IN (SELECT *
              FROM v$sql
             WHERE upper(sql_fulltext) LIKE '%ABC.TRN%')
  LOOP
    INSERT INTO log_of_bad_sql( sql_fulltext, <<other columns>> )
      VALUES( x.sql_fulltext, <<other columns>> );
  END LOOP;
END;
创建或过程查找\u abc\u trn
作为
开始
对于x英寸(选择*
从v$sql
其中上部(sql_全文)如“%ABC.TRN%”
环
插入错误sql(sql完整)的日志