• plsql可执行别的用户对象,过程却不行(AUTHID CURRENT_USER)


     问题描述:

    如表rm_circuit是a用户的,授予b用户select,insert,update,delete权限,在b用的存储过程中执行dbms_stats.gather_table_stats提示:ora-020000:unable to analyze table "a"."rm_circuit",insufficient privileges or does not exist.但是直接在plsql中在b用户下执行begin dbms_stats.gather_table_stats('a','rm_circuit');end;可以成功执行。如果没有权限,怎么b用户用plsql就可以执行呢

    问题原因:

    procedure需要显示的授权,虽然对表已经授权了,但是在过程中是无效的。

    解决办法:

    1、在过程中加上对表进行授权的操作;

    2、在过程中加上 AUTHID CURRENT_USER 。

    之前就接触过几次 AUTHID CURRENT_USER ,但是也没仔细的研究过。今天花了大半天时间测试测试了这个东西的使用。具体如下:

    AUTHID CURRENT_USER
    如果在包中或过程中加上 AUTHID CURRENT_USER 表示以调用者的身份执行。默认情况下以定义者身份执行。
    定义者身份:在执行中,当前用户只有除角色权限外的权限。
    调用者身份:在执行中,当前用户拥有已经授以的所有权限(包含角色权限和系统权限)。


    测试1:
    GWM用户拥有的角色权限和系统权限如下所示:

    执行用户:gwm。分析的表:lttfm用户下的b$i_exch_info表。
    1、在平常的plsql中执行如下语句,以下语句分析表成功,说明该用户即使没有显式的授权分析任何表的权限,但是由于该用户具有dba角色权限可以进行分析任何表
    begin dbms_stats.gather_table_stats('lttfm','b$i_exch_info');end;--执行成功

    2、用过程对表进行分析。执行失败。说明在执行过程时默认是以定义者身份执行,对于角色权限是无效的。
    CREATE OR REPLACE PROCEDURE p_authiduser_test  IS
    BEGIN
        dbms_stats.gather_table_stats('lttfm','b$i_exch_info');
    END p_authiduser_test;

    执行过程提示错误:
    SQL> EXEC gwm.p_authiduser_test;
    begin gwm.p_authiduser_test; end;
     
    ORA-20000: Unable to analyze TABLE "LTTFM"."B$I_EXCH_INFO", insufficient privileges or does not exist
    ORA-06512: 在 "SYS.DBMS_STATS", line 13046
    ORA-06512: 在 "SYS.DBMS_STATS", line 13076
    ORA-06512: 在 "GWM.P_AUTHIDUSER_TEST", line 6
    ORA-06512: 在 line 2

    3、对gwm用户授以分析任何表的权限,执行过程成功。说明定义者身份执行过程只认显式授以的权限。
    grant analyze any to gwm;

    SQL> EXEC gwm.p_authiduser_test;
    PL/SQL procedure successfully completed

    4、或者收回分析任何表权限,在过程上加上 AUTHID CURRENT_USER。执行如下过程,也可以成功执行。说明过程以调用者身份执行能够识别角色权限。
    revoke analyze any from gwm;
    CREATE OR REPLACE PROCEDURE p_authiduser_test AUTHID CURRENT_USER IS
    BEGIN
        dbms_stats.gather_table_stats('lttfm','b$i_exch_info');
    END p_authiduser_test;


    测试2:以另一个用户来执行
    revoke analyze any from gwm;
    转到ltwebgis用户
    执行如下过程无法成功执行。仍然如测试1中2的提示:
    CREATE OR REPLACE PROCEDURE p_authiduser_test IS
    BEGIN
        dbms_stats.gather_table_stats('lttfm','b$i_exch_info');
    END p_authiduser_test;

    如果对gwm授以分析任何表权限或者直接在过程中加上 AUTHID CURRENT_USER ,在ltwebgis用户下执行过程也可以成功创建表。
    SQL> EXEC gwm.p_authiduser_test;
    PL/SQL procedure successfully completed


    测试3:测试 AUTHID CURRENT_USER 在执行过程中对操作用户的影响
    测试过程:创建该过程的用户:gwm
    CREATE OR REPLACE PROCEDURE p_authiduser_test IS
      v_session_user   VARCHAR2(255);
      v_current_user   VARCHAR2(255);
      v_current_schema VARCHAR2(255);
    BEGIN
      SELECT sys_context('userenv', 'session_user') session_user,
             sys_context('userenv', 'current_user') current_user,
             sys_context('userenv', 'current_schema') current_schema
        INTO v_session_user, v_current_user, v_current_schema
        FROM dual;
      dbms_output.put_line('session_user:'||v_session_user);
      dbms_output.put_line('current_user:'||v_current_user);
      dbms_output.put_line('current_schema:'||v_current_schema);
      /*dbms_stats.gather_table_stats('lttfm', 'b$i_exch_info');*/
    END p_authiduser_test;

    gwm用户下执行该过程:
    SQL> SET SERVEROUTPUT ON;
    SQL>  EXEC p_authiduser_test;
    session_user:GWM
    current_user:GWM
    current_schema:GWM

    转到ltwebgis用户下执行:
    SQL> SET SERVEROUTPUT ON;
    SQL> EXEC gwm.p_authiduser_test;
    session_user:LTWEBGIS
    current_user:GWM
    current_schema:GWM

    修改过程如下,即加上AUTHID CURRENT_USER

    CREATE OR REPLACE PROCEDURE p_authiduser_test AUTHID CURRENT_USER IS
      v_session_user   VARCHAR2(255);
      v_current_user   VARCHAR2(255);
      v_current_schema VARCHAR2(255);
    BEGIN
      SELECT sys_context('userenv', 'session_user') session_user,
             sys_context('userenv', 'current_user') current_user,
             sys_context('userenv', 'current_schema') current_schema
        INTO v_session_user, v_current_user, v_current_schema
        FROM dual;
      dbms_output.put_line('session_user:'||v_session_user);
      dbms_output.put_line('current_user:'||v_current_user);
      dbms_output.put_line('current_schema:'||v_current_schema);
      /*dbms_stats.gather_table_stats('lttfm', 'b$i_exch_info');*/
    END p_authiduser_test;

    gwm用户下执行:
    SQL> SET SERVEROUTPUT ON;
    SQL>  EXEC p_authiduser_test;
    session_user:GWM
    current_user:GWM
    current_schema:GWM

    转到ltwebgis用户下执行:
    SQL> SET SERVEROUTPUT ON;
    SQL> EXEC gwm.p_authiduser_test;
    session_user:LTWEBGIS
    current_user:LTWEBGIS
    current_schema:LTWEBGIS

    如测试3可得出:
    1、如果是本用户gwm执行,不管是否加上 AUTHID CURRENT_USER 即不管是以定义者还是调用者身份执行,其打开的会话,当前用户,当前的模式都是gwm,唯一的区别是不同身份的执行其获取的权限不同。
    2、如果是用别的用户ltwebgis用户来执行,如果不加 AUTHID CURRENT_USER ,只是打开的会话用户是ltwebgis,执行过程的当前用户和当前模式都是gwm;但是如果加上 AUTHID CURRENT_USER ,则执行的时候就完全是以ltwebgis用户进行操作了,创建的表使用的表都是以ltwebgis用户所拥有的。

    如下过程创建一个表:该过程是gwm用户下的。
    CREATE OR REPLACE PROCEDURE p_authiduser_test AUTHID CURRENT_USER IS
    BEGIN
      EXECUTE IMMEDIATE 'CREATE TABLE fyzh_test (id NUMBER,name VARCHAR2(255))';
    END p_authiduser_test;
    如果是gwm用户执行,不管是否加了AUTHID CURRENT_USER,创建的表都是gwm用户下的;但是如果是在ltwebgis用户执行该过程,不加
    AUTHID CURRENT_USER 这个的话,执行其过程创建的表是gwm用户的(如上结论可知其执行的用户仍为gwm),如果加了 AUTHID CURRENT_USER,
    创建的表就是ltwebgis用户下的(如上结论可知加上AUTHID CURRENT_USER这个,在ltwebgis用户下执行该过程其操作的用户就是ltwebgis)。

     随后又出现了问题:

    在过程中加入AUTHID CURRENT_USER后,手动执行该过程倒是可以了,但是发现job执行仍然无法成功,仍提示没有足够的权限。

    看来对于job无法识别AUTHID CURRENT_USER。没找到更好的办法,只能先显式的对用户进行授权,解决该问题。

     
  • 相关阅读:
    Machine Learning/Introducing Logistic Function
    学习Machine Leaning In Action(四):逻辑回归
    极致和厚道为小米新国货的核心实质(极致不是指最好的,而是要超乎预期)
    做事要提前留有余地,否则到时候就来不及了(超市买菜,找工作,交朋友,发脾气都是如此)
    UpdateWindow API函数的作用很明显
    近几年前端技术盘点以及 2016 年技术发展方向
    使用SetLocaleInfo设置时间后必须调用广播WM_SETTINGCHANGE,通知其他程序格式已经更改
    设计模式——(Abstract Factory)抽象工厂
    从优化到再优化,最长公共子串
    与数据库打交道的Adapter----SimpleCursorAdapter
  • 原文地址:https://www.cnblogs.com/lanzi/p/2143554.html
Copyright © 2020-2023  润新知