首先尝试创建一个ACL
07:20:03 SQL> declare
ace_list xs$ace_list;
begin
ace_list:=xs$ace_list(xs$ace_type(privilege_list=>xs$name_list('"administer_session"'),granted=>true,principal_name=>'xs_user_10'),
xs$ace_type(privilege_list=>xs$name_list('"create_session"','"modify_session"','"attach_session"'),granted=>true,principal_name=>'xs_user_11'),
xs$ace_type(privilege_list=>xs$name_list('"create_session"','"modify_session"'),granted=>true,principal_name=>'xs_user_12'));
xs_acl.create_acl(name=>'wgz_acl',ace_list=>ace_list,sec_class=>'sessionprivs',description=>'wgz session management');
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.17
创建上面的三个application user,并将ACL赋予这三个用户。
07:22:58 SQL> exec xs_principal.create_user(name=>'xs_user_10',schema=>'sys',acl=>'wgz_acl');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02
07:42:52 SQL> exec xs_principal.set_password(user=>'xs_user_10',password=>'tdetest2');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02
07:43:15 SQL> exec xs_principal.create_user(name=>'xs_user_11',schema=>'sys',acl=>'wgz_acl');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
07:44:34 SQL> exec xs_principal.set_password(user=>'xs_user_11',password=>'tdetest2');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
07:45:18 SQL> exec xs_principal.create_user(name=>'xs_user_12',schema=>'sys');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
07:46:33 SQL> exec xs_principal.set_acl(principal=>'xs_user_12',acl=>'wgz_acl');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
查看创建的ACL及ACE
08:12:23 SQL> select name,owner,security_class,security_class_owner,description from dba_xs_acls;
NAME OWNER SECURITY_CLASS SECURITY_CLASS_ DESCRIPTION
------------------------------------------------------------ ---------- --------------- --------------- ----------------------------------------------------------------------
SYSTEMACL SYS SYSTEM SYS Default ACL for System Security Class
XS$SCHEMA_ACL DBSFWUSER SYSTEM SYS
SESSIONACL SYS SESSION_SC SYS Default ACL for Session Security Class
NS_UNRESTRICTED_ACL SYS NSTEMPLATE_SC SYS Seeded ACL to grant ADMIN_NAMESPACE privilege to PUBLIC
NETWORK_ACL_B193F39A153A639FE0537885E50AB8A6 SYS NETWORK_SC SYS ACL for host *:*
NETWORK_ACL_B194333D66523F0AE0537885E50A8396 SYS NETWORK_SC SYS ACL for web service access from MDSYS
WGZ_ACL PDBADMIN SESSIONPRIVS PDBADMIN wgz session management
08:15:49 SQL> select acl,owner,ace_order,grant_type,principal,principal_type,privilege,security_class,security_class_owner from dba_xs_aces order by acl,ace_order;
ACL OWNER ACE_ORDER GRANT PRINCIPAL PRINCIPAL_T PRIVILEGE SECURITY_CLASS SECURITY_CLASS_
-------------------------------------------------- ---------- ---------- ----- -------------------- ----------- -------------------- --------------- ---------------
NETWORK_ACL_B193F39A153A639FE0537885E50AB8A6 SYS 1 GRANT GSMADMIN_INTERNAL DATABASE RESOLVE NETWORK_SC SYS
NETWORK_ACL_B193F39A153A639FE0537885E50AB8A6 SYS 2 GRANT GGSYS DATABASE RESOLVE NETWORK_SC SYS
NETWORK_ACL_B194333D66523F0AE0537885E50A8396 SYS 1 GRANT MDSYS DATABASE CONNECT NETWORK_SC SYS
NS_UNRESTRICTED_ACL SYS 1 GRANT PUBLIC DATABASE ADMIN_NAMESPACE NSTEMPLATE_SC SYS
NS_UNRESTRICTED_ACL SYS 2 GRANT XSPUBLIC APPLICATION ADMIN_NAMESPACE NSTEMPLATE_SC SYS
SESSIONACL SYS 1 GRANT XS_SESSION_ADMIN DATABASE ADMINISTER_SESSION SESSION_SC SYS
SESSIONACL SYS 2 GRANT XSSESSIONADMIN APPLICATION ADMINISTER_SESSION SESSION_SC SYS
SESSIONACL SYS 3 GRANT U_2 DATABASE MODIFY_SESSION SESSION_SC SYS
SYSTEMACL SYS 1 GRANT SYS DATABASE CALLBACK SYSTEM SYS
SYSTEMACL SYS 1 GRANT SYS DATABASE PROVISION SYSTEM SYS
SYSTEMACL SYS 2 GRANT XSPROVISIONER APPLICATION CALLBACK SYSTEM SYS
SYSTEMACL SYS 2 GRANT XSPROVISIONER APPLICATION PROVISION SYSTEM SYS
SYSTEMACL SYS 3 GRANT PROVISIONER DATABASE CALLBACK SYSTEM SYS
SYSTEMACL SYS 3 GRANT PROVISIONER DATABASE PROVISION SYSTEM SYS
SYSTEMACL SYS 4 GRANT DBA DATABASE ADMIN_ANY_SEC_POLICY SYSTEM SYS
SYSTEMACL SYS 7 GRANT DBA DATABASE ADMIN_ANY_NAMESPACE SYSTEM SYS
SYSTEMACL SYS 8 GRANT XS_NAMESPACE_ADMIN DATABASE ADMIN_ANY_NAMESPACE SYSTEM SYS
SYSTEMACL SYS 9 GRANT XSNAMESPACEADMIN APPLICATION ADMIN_ANY_NAMESPACE SYSTEM SYS
SYSTEMACL SYS 10 GRANT MIDTIER_AUTH APPLICATION ADMIN_ANY_NAMESPACE SYSTEM SYS
SYSTEMACL SYS 11 GRANT OLAP_XS_ADMIN DATABASE ADMIN_SEC_POLICY SYSTEM SYS
SYSTEMACL SYS 12 GRANT SEC_MGR DATABASE PROVISION SYSTEM SYS
SYSTEMACL SYS 13 GRANT PDBADMIN DATABASE PROVISION SYSTEM SYS
WGZ_ACL PDBADMIN 1 GRANT XS_USER_10 APPLICATION administer_session SESSIONPRIVS PDBADMIN
WGZ_ACL PDBADMIN 2 GRANT XS_USER_11 APPLICATION attach_session SESSIONPRIVS PDBADMIN
WGZ_ACL PDBADMIN 2 GRANT XS_USER_11 APPLICATION create_session SESSIONPRIVS PDBADMIN
WGZ_ACL PDBADMIN 2 GRANT XS_USER_11 APPLICATION modify_session SESSIONPRIVS PDBADMIN
WGZ_ACL PDBADMIN 3 GRANT XS_USER_12 APPLICATION create_session SESSIONPRIVS PDBADMIN
WGZ_ACL PDBADMIN 3 GRANT XS_USER_12 APPLICATION modify_session SESSIONPRIVS PDBADMIN
XS$SCHEMA_ACL DBSFWUSER 1 GRANT DBSFWUSER DATABASE ADMIN_SEC_POLICY SYSTEM SYS
29 rows selected.
Elapsed: 00:00:00.02
上面通过ACL赋予xs_user_10的administer_session权限是管理application session,也可以说是light weight session,如果想创建database session,也就是heavyweight session,则必须另外赋予role
[oracle@scaqai06adm07 bin]$ ./sqlplus "xs_user_10/tdetest2@scaqai06adm07:1521/tdetest2pdb10888"
SQL*Plus: Release 21.0.0.0.0 - Production on Mon Feb 15 08:27:44 2021
Version 21.1.0.0.0
Copyright (c) 1982, 2020, Oracle. All rights reserved.
ERROR:
ORA-01045: user XS_USER_10 lacks CREATE SESSION privilege; logon denied
上面报错的原因就是因为没有创建heavyweight session的权限
08:29:09 SQL> exec xs_principal.grant_roles('xs_user_10','xsdba');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
现在验证ACL是不是起了作用
使用xs_user_10能够直接登录数据库,说明xs_user_10这个application user即具有了创建heavyweight session的权限,也具有了创建light weight session的权限
[oracle@scaqai06adm07 bin]$ ./sqlplus "xs_user_10/tdetest2@scaqai06adm07:1521/tdetest2pdb10888"
SQL*Plus: Release 21.0.0.0.0 - Production on Mon Feb 15 08:32:23 2021
Version 21.1.0.0.0
Copyright (c) 1982, 2020, Oracle. All rights reserved.
Connected to:
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.1.0.0.0
08:32:23 SQL> show user;
USER is "XS_USER_10"
08:32:59 SQL> select user_name,sessionid,database_sessionid from dba_xs_active_sessions;
USER_NAME SESSIONID DATABASE_SESSIONID
-------------------- -------------------------------- ------------------
XS_USER_10 BB6387D55069D8F9E053D529850A97C2 6419
Elapsed: 00:00:00.01
能够从dba_xs_active_sessions里面查看到这个application session已经attach到了一个database session,所以说明attach session的权限也有了
08:34:03 SQL> select user_name,sessionid from dba_xs_sessions;
USER_NAME SESSIONID
-------------------- --------------------------------
XS_USER_10 BB6387D55069D8F9E053D529850A97C2
Elapsed: 00:00:00.00
08:35:14 SQL> exec dbms_xs_sessions.set_session_cookie('cookie_test_xs_user_10','BB6387D55069D8F9E053D529850A97C2');
BEGIN dbms_xs_sessions.set_session_cookie('cookie_test_xs_user_10','BB6387D55069D8F9E053D529850A97C2'); END;
*
ERROR at line 1:
ORA-46070: insufficient privileges
ORA-06512: at "SYS.DBMS_XS_SESSIONS_FFI", line 303
ORA-06512: at "SYS.DBMS_XS_SESSIONS", line 193
ORA-06512: at line 1
Elapsed: 00:00:00.01
可这么的错误说明是没有alter session的权限啊,命名administer_session是包含modify session这个权限的呢?这是怎么回事?
下面是分析错误的过程ORA-46070: insufficient privileges
已经对xs_user_10这个application user赋予了xsdba这个application role,这个application role xsdba已经被赋予了database role dba,莫非database role dba没有alter session的权限?
08:52:35 SQL> select grantee,privilege from dba_sys_privs where privilege='ALTER SESSION' and grantee='DBA';
GRANTEE PRIVILEGE
-------------------- -------------
DBA ALTER SESSION
Elapsed: 00:00:00.01
DBA这个角色也有alter session的权限,不知道是为什么
下面采取首先用一个database user pdbadmin连接数据库的方式来操作一下
[oracle@scaqai06adm07 bin]$ ./sqlplus "pdbadmin/tdetest2@scaqai06adm07:1521/tdetest2pdb10888"
SQL*Plus: Release 21.0.0.0.0 - Production on Mon Feb 15 08:54:39 2021
Version 21.1.0.0.0
Copyright (c) 1982, 2020, Oracle. All rights reserved.
Last Successful login time: Mon Feb 15 2021 07:20:03 -08:00
Connected to:
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.1.0.0.0
08:54:40 SQL> declare
08:54:50 2 sid raw(16);
08:54:54 3 begin
08:54:56 4 dbms_xs_sessions.create_session('xs_user_10',sid);
08:55:14 5 dbms_xs_sessions.attach_session(sid);
08:55:24 6 dbms_xs_sessions.set_session_cookie('cookie_test_xs_user_10',sid);
08:55:43 7 end;
08:55:45 8 /
declare
*
ERROR at line 1:
ORA-46070: insufficient privileges
ORA-06512: at "SYS.DBMS_XS_SESSIONS_FFI", line 303
ORA-06512: at "SYS.DBMS_XS_SESSIONS", line 193
ORA-06512: at line 6
Elapsed: 00:00:00.02
还是碰到这个错误,
下面单独赋予xs_user_10这个用户 modify_session的权限
08:58:05 SQL> exec xs_acl.grant_privilege(acl=>'wgz_acl',privilege=>'modify_session',principal=>'xs_user_10');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02
09:02:27 SQL> select acl,ace_order,grant_type,principal,privilege from dba_xs_aces where acl='WGZ_ACL' order by ace_order;
ACL ACE_ORDER GRANT PRINCIPAL PRIVILEGE
-------------------------------------------------- ---------- ----- -------------------- --------------------
WGZ_ACL 1 GRANT XS_USER_10 administer_session
WGZ_ACL 2 GRANT XS_USER_11 modify_session
WGZ_ACL 2 GRANT XS_USER_11 create_session
WGZ_ACL 2 GRANT XS_USER_11 attach_session
WGZ_ACL 3 GRANT XS_USER_12 create_session
WGZ_ACL 3 GRANT XS_USER_12 modify_session
WGZ_ACL 4 GRANT XS_USER_10 MODIFY_SESSION
7 rows selected.
可以看到单独对xs_user_10这个用户赋予了modify_session这个权限了
在赋予了这个权限之后还是不能set session cookie
09:12:41 SQL> declare
09:12:47 2 sid raw(16);
09:12:50 3 begin
09:12:52 4 dbms_xs_sessions.create_session('xs_user_10',sid);
09:13:05 5 dbms_xs_sessions.attach_session(sid);
09:13:15 6 dbms_xs_sessions.set_session_cookie('cookie_in_problem',sid);
09:13:34 7 end;
09:13:35 8 /
declare
*
ERROR at line 1:
ORA-46070: insufficient privileges
ORA-06512: at "SYS.DBMS_XS_SESSIONS_FFI", line 303
ORA-06512: at "SYS.DBMS_XS_SESSIONS", line 193
ORA-06512: at line 6
Elapsed: 00:00:00.01
就是因为加了ACL,所以导致无法set_session_cookie,所以问题肯定是在ACL这里,明天可以尝试将ACL去除试试看
明天排查问题,首先将这个ACL删除掉,然后使用sys用户创建一遍试试(通过最终的排查,问题不在于这个ACL是sys创建,还是pdbadmin这个用户创建,和创建用户无关)
要不就是在systemacl那个ACL加上看看,在这个里面加,应该是要调用xs_admin_util.grant_system_privilege这个procedure
首先我删除了这个ACL,然后用sys用户重新建了一遍
我故意将其中一个权限写错了administer_session1,发现没有 报错,说明在权限名称这里没有进行验证,对于user这里,其实也没有验证这个user是不是真的存在
所以得到的教训就是权限这里要用大写写,不能用小写
(最终结论是其实用小写写,也没问题,小写一样能够执行成功,所以不是小写的问题,虽然将权限写错了也不报错administer_session1)
00:12:50 SQL> show user;
USER is "SYS"
00:14:23 SQL> declare
ace_list xs$ace_list;
begin
ace_list:=xs$ace_list(xs$ace_type(privilege_list=>xs$name_list('"administer_session1"'),granted=>true,principal_name=>'xs_user_10'),
xs$ace_type(privilege_list=>xs$name_list('"create_session"','"modify_session"','"attach_session"'),granted=>true,principal_name=>'xs_user_11'),
xs$ace_type(privilege_list=>xs$name_list('"create_session"','"modify_session"'),granted=>true,principal_name=>'xs_user_12'));
xs_acl.create_acl(n00:14:30 2 ame=>'wgz_acl',ace_list=>ace_list,sec_class=>'sessionprivs',description=>'wgz session management');
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02
最后解决问题的方法是通过xs_admin_util.grant_system_privilege这个方法来实现的,执行了这个procedure之后,在set_session_cookie就不会报错了
具体ACL哪里出了错,没找出来
00:40:15 SQL> exec xs_admin_util.grant_system_privilege('MODIFY_SESSION','XS_USER_10',xs_admin_util.ptype_xs);
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
00:42:16 SQL> exec dbms_xs_sessions.set_session_cookie('ccc');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
终于找到问题之所在了,通过查询dba_xs_objects这个视图,发现里面有个对象sessionprivs 是invalid的,我发现调用xs_acl.create_acl如果指定的security class不存在的话,则会默认创建这个security class,问题就出在了这里,这个security class的状态为invalid在dba_xs_objects里面查询(造成这个错误的原因是直接从文档上抄的例子,文档上有错误)
通过指定已经存在的security class SESSION_SC,则会解决问题
01:53:09 SQL> declare
ace_list xs$ace_list;
begin
ace_list:=xs$ace_list(xs$ace_type(privilege_list=>xs$name_list('"ADMINISTER_SESSION"'),granted=>true,principal_name=>'xs_user_10'),
xs$ace_type(privilege_list=>xs$name_list('"CREATE_SESSION"','"MODIFY_SESSION"','"ATTACH_SESSION"'),granted=>true,principal_name=>'xs_user_11'),
xs$ace_type(privilege_list=>xs$name_list('"CREATE_SESSION"','"MODIFY_SESSION"'),granted=>true,principal_name=>'xs_user_12'));
xs_acl.create_acl(name=>'wgz_acl',ace_list=>ace_list,sec_class=>'SESSION_SC',description=>'wgz session management');
01:54:42 2 end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
01:54:42 SQL> exec xs_principal.set_acl('xs_user_10','wgz_acl');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
结论:
1.在创建ACL时,privilege的名称并不验证,但是用小写,也没问题。在xs n a m e l i s t 指 定 权 限 时 x s name_list指定权限时 xs namelist指定权限时xsname_list(’“ADMINISTER_SESSION”’) ,加不加双引号都行(使用不使用双引号都不进行权限验证),加了双引号,则大小写会和dba_xs_aces里的大小写一致,如果不使用双引号,则无论使用大小写,在视图dba_xs_aces里面查询都是大写。
2.使用sys用户或者别的用户创建ACL,都没问题
3.在创建ACL时,要指定正确的security class,指定错误的security class,create application session和attach application session没问题,但是set application session的cookie时就会有问题
4.使用xs_admin_util.grant_system_privilege这个procedure给application user设置权限后,也可以解决问题。ACL和通过xs_admin_util.grant_system_privilege算是两个层次,xs_admin_util.grant_sysem_privilege这个是在修改sessionacl这个ACL。
############################################
等有时间整理一遍没有错误的执行过程
##############################################