日期:2014-05-16  浏览次数:20474 次

Oracle Proxy Authentication(代理身份认证)

一 首先看一下Oracle官方给出的介绍:

Oracle 代理身份验证在 Oracle8i 中首次推出,旨在为应用程序开发人员在设计多层体系结构时提供更多的灵活性。由于能够满足基于 Internet 的应用程序的伸缩性需求,多层体系结构在二十世纪九十年代开始流行。它们包含两个组件 — 一个中间层和一个后端数据库。基于 Oracle 的多层体系结构包含 Oracle 融合中间件和 Oracle 数据库。目前,很多应用程序仅仅将用户认证到中间层,而中间层则作为一个大用户连接到数据库。只要后端数据库不要求最终用户的身份,该模型就能够起作用。在过去的 5 年中,身份传播对于合规性和整体安全而言已经变得越来越重要。身份传播能够以多种方式实现。

现有的多层应用程序使用的最常见的方法是,通过现有的单个大用户连接将客户端标识符从中间层传递到后端数据库。客户端标识符在 Oracle 数据库 9i 中引入,旨在让应用程序通过现有的胖或瘦 JDBC 连接将标识符从中间层传递到后端数据库。当 Oracle 数据库审计启动后,客户端标识符将被记录到 Oracle 数据库审计线索中。一旦完成初始化,客户端标识符的值可以通过任意 SQL 或 PL/SQL 语句在数据库中进行引用。

  STEVE> select sys_context('userenv','client_identifier') from dual;

要通过 OCI 设置 CLIENT_IDENTIFIER 属性,在调用 OCIAttrSet() 时使用 OCI_ATTR_CLIENT_IDENTIFIER 属性。然后,在下次请求服务器时,信息会传播并存储在服务器会话中。例如:

  OCIAttrSet (session,
  OCI_HTYPE_SESSION,
  (dvoid *) "appuser1",
  (ub4)strlen("appuser1"),
  OCI_ATTR_CLIENT_IDENTIFIER,
  error_handle); /* OCIError *error_handle */

对于使用 JDBC 的应用程序而言,在连接池环境中,客户端标识符可用于识别哪个轻量级用户当前正在使用数据库会话。要为 JDBC 应用程序设置 CLIENT_IDENTIFIER,使用下面的 oracle.jdbc.OracleConnection 接口方法:

setClientIdentifier():为连接设置客户端标识符
clearClientIdentifier():为连接清除客户端标识符

要了解更多信息,请参考 Oracle 调用接口编程人员指南和 Oracle 数据库 JDBC 开发人员指南及参考手册。

另一种方法是,应用程序可使用传统的代理身份验证将真实的最终用户身份验证到后端数据库,然后再代理到单个大用户。该方法可与 Oracle 企业用户安全性结合使用。利用企业用户安全性,可在后端数据库中定义一个共享模式,从而极大地减少 Oracle 数据库用于处理最终用户所需的数据库帐户数量。在 Oracle 数据库 10g 第 2 版之前,Oracle 代理身份验证只能与胖或瘦 JDBC 连接结合使用。在 Oracle 数据库 10g 第 2 版中,Oracle 引入了命令行代理功能。

命令行代理功能对于在后端服务器上执行批量任务以及作为单个大用户进行连接尤其有用。

  SYSTEM> grant create session to Steve identified by steve_password;
  SYSTEM> grant create session to sales_app_dba identified
          by sales_app_dba_password;

  SYSTEM> alter user sales_app_dba grant connect through Steve;

  SYSTEM> connect Steve[sales_app_dba]/steve_password;
  
  SALES_APP_DBA>

注意,steve 的口令也可通过安全的外部口令存储特性存储在 Oracle 钱夹中。命令行代理可与安全的外部口令存储一同使用,为保障批量任务提供出色的解决方案。


二 再看一下Tom Kyte的例子演示:

说明:下面的例子将演示用户A如何担任用户B的角色,从而能够在不知道B的密码情况下操作B用户下的对象,并使用B用户拥有的部分权限。Let's do it.

1、创建两用户 A 和 B:

SYS@orcl> create user a identified by a;

用户已创建。

SYS@orcl> grant
  2       create session,
  3       create procedure
  4       to a;

授权成功。

SYS@orcl> create user b identified by b default tablespace users
  2       quota unlimited on users;

用户已创建。

SYS@orcl> grant create session, create table, create procedure to b;

授权成功。


2、通过ALTER USER语句使 A “become B”:

SYS@orcl> alter user b grant connect through a;

用户已更改。

SYS@orcl> connect b/b
已连接。
B@orcl> create
  2     procedure p
  3     as
  4     begin
  5       null;
  6     end;
  7  /

过程已创建。

B@orcl> conn a/a
已连接。
A@orcl> show user
USER 为 "A"

3、下面咱们通过 A 作为B用户登录执行相关操作:

A@orcl> conn a[b]/a
已连接。
B@orcl> show user
USER 为 "B"
  1  create or replace
  2     procedure p
  3     as
  4     begin
  5       dbms_output.put_line('new stuff');
  6*    end;
B@orcl> /

过程已创建。
B@orcl> create table t2 (x int);

表已创建。

B@orcl> grant execute on p to a;

授权成功。
B@orcl> conn a/a
已连接。
A@orcl> exec b.p
new stuff

PL/SQL 过程已成功完成。

OK.  效果一目了然!


4、但此时我不想用户A 拥有 B 的“CREATE TABLE”权限,又应该如何阻止呢?OK,我们可以将用户B的 “CREATE TABLE” 权限与 “CREATE SESSION” 、

“CREATE PROCEDURE”权限分开,通过重建用户B ,创建2个不同的角色实现, as follows:

A@orcl> conn / as sysdba
已连接。
SYS@orcl> create role b_role1;

角色已创建。

SYS@orcl> create role b_role2;

角色已创建。

SYS@orcl> grant
  2       create procedure,
  3       create session
  4       to b_role1;

授权成功。

SYS@orcl> grant
  2       crea