Weblog

Oracle Proxy Users by example

The following example illustrates the use of Oracle proxy users. If you wonder what proxy users are, have a look at my previous posting: Oracle Proxy Users.

First we’ll create two database users. One normal application user, pu_user_1, and a Big Application User, pu_pool_user. The big application user will be used by a web application to connect to the database. Usually the application user, in this case pu_user_1, will be authenticated by the web application.

create user pu_pool_user identified by pu_pool_user;
grant create session to pu_pool_user;

create user pu_user_1 identified by pu_user_1;
alter user pu_user_1 grant connect through pu_pool_user;
grant create session to pu_user_1;

By granting pu_user_1 the connect through privilege, you allow pu_pool_user to proxy for pu_user_1, i.e., pu_pool_user connects to the database, but it will be as if pu_user_1 is connected.

First a normal connection. The following example connects to oracle using the user pu_pool_user:

    private void normalConnection() throws Exception {
        Properties properties = new Properties();
        Connection conn = DriverManager.getConnection(
                "jdbc:oracle:thin:pu_pool_user/pu_pool_user@localhost:1521:ora1012",
                properties);
        printUserInfo(conn);
        conn.close();
    }

If you ask oracle who is connected, oracle will identify the connected user as pu_pool_user. This is displayed using the following code:

    private void printUserInfo(Connection conn) throws Exception {
        System.out.println(
            "Is proxy session: " + ((OracleConnection) conn).isProxySession());

        PreparedStatement stmt = conn.prepareStatement(
                " select user, username "
                 +", sys_context('USERENV','PROXY_USER') "
                 +", sys_context('USERENV','CURRENT_USER') "
                 +", sys_context('USERENV','SESSION_USER') "
                 +" from sys.v_$session"
                );
        ResultSet rset = stmt.executeQuery();

        if (rset.next()) {
            System.out.println("user                  : " + rset.getString(1));
            System.out.println("username              : " + rset.getString(2));
            System.out.println("userenv proxy_user    : " + rset.getString(3));
            System.out.println("userenv current_user  : " + rset.getString(4));
            System.out.println("userenv session_user  : " + rset.getString(5));
        }

        stmt.close();
    }

This method prints the following info for the normal connection:

Is proxy session: false
user                  : PU_POOL_USER
username              : null
userenv proxy_user    : null
userenv current_user  : PU_POOL_USER
userenv session_user  : PU_POOL_USER

The following code connects to the database as pu_pool_user, but then we tell the connection that we’re actually proxying for pu_user_1.

    private void proxyConnection() throws Exception {
        Properties properties = new Properties();
        properties.put("PROXY_USER_NAME", "pu_user_1");

        OracleConnection conn = (OracleConnection) DriverManager.getConnection(
                "jdbc:oracle:thin:pu_pool_user/pu_pool_user@localhost:1521:ora1012",
                properties);
        conn.openProxySession(OracleConnection.PROXYTYPE_USER_NAME, properties);

        printUserInfo(conn);
        conn.close();
    }

The result of calling printUserInfo:

Is proxy session: true
user                  : PU_USER_1
username              : PU_USER_1
userenv proxy_user    : PU_POOL_USER
userenv current_user  : PU_USER_1
userenv session_user  : PU_USER_1

As you can see, USER now returns PU_USER_1, eventhough we connected to the database as pu_pool_user.

This is very convenient, you do not have to rewrite your security code and your auditing code.

Share and Enjoy:
  • del.icio.us
  • Google Bookmarks
  • DZone
  • LinkedIn
  • SphereIt
  • StumbleUpon
  • Technorati

14 Responses to “Oracle Proxy Users by example”

  1. venky Says:

    Hi,

    Wanted to know if there are any drawbacks in using the proxy user approach, especially in the following areas:
    - effects on connection pooling (as connections would be pooled using the Big Application User)
    - overhead in authenticating every time a database connection is acquired

    Regards,

    Venky

  2. Andrej Koelewijn Says:

    I’m not aware of any drawbacks.
    - Most web applications have a big application user, even if they don’t use proxy users. Not much difference.
    - Are you sure authentication is performed every time a database connection is acquired? I would expect the oracle jdbc drivers to cache authentication information.

  3. dfc Says:

    One question I have, looking at your example, there’s no password sent for the individual user. Doesn’t that sort of defeat the point of proxying the user, if you can’t authenticate that it is that user? Or am I missing something? Was a line or two left out of the example?

  4. Andrej Koelewijn Says:

    A proxy user is authenticated by the application server. The database trusts the application to have authenticated the user.

  5. doug Says:

    What about roles does the biguser need to be granted a union of all the roles of the users it proxies or can it have none and not be priviledged beyon create session?

  6. paly Says:

    Hi,

    Suppose we have a “owner schema” that owns all the objects of the application.

    How are defined the users pu_user_1 ? They must have synonyms to the owner schema ?
    What would you recommand ?

  7. Andrej Koelewijn Says:

    I think that there’s no difference when using proxy users or not in this respect. A user needs to be able to access objects in another schema, so you need either public synonyms, private synonyms or a fully qualified naming and the required privileges.

  8. Peter Meiller Says:

    Responding to dfc:

    In the oracle 10.2 sql doc, there is an “authentication required” clause on the “alter user pu_user_1″ which forces a password to be supplied when the proxy user switches over to the other user

    I haven’t ever done it but that is what is in the docs

  9. Peter Meiller Says:

    Just an update

    The authentication required clause works fine

  10. Saso Stojanovski Says:

    I just tried out your code, and I get an error saying that

    OracleConnection.PROXYTYPE_USER_NAME cannot be resolved

    and

    The method isProxySession() is undefined for the type OracleConnection

    i am using ojdbc14.jar in my classpath. please help

  11. Thinhbk Says:

    Hi,
    I want to ask one thing,that’s implement VPD using proxy_user to grant access for user.My trouble is that user from remote connect to database using database link,in which the user in database link is different from this current user,(certainly on server,this user have role to access data).I want to ask:how can we paypass this?how to implementation authentication that transparent to location of the user(because i’m using database link).
    Thanks for all answer!

  12. Jaffrin Says:

    We are implementing Proxy authentication in our project.We are using Oracle Clinet9.0.4.0.1, I am using OracleOCIConnecionPooling to establish proxy connection,However I am getting some ecxeption that i dont understand. Here is the code
    OracleOCIConnectionPool cpool=new OracleOCIConnectionPool(“username”,”password”,”jdbc:oracle:oci:@(description=(address=(host=hostname)(protocol=tcp)(port=1529))(connect_data=(sid=databasename)))”,poolConfig);
    Properties prop=new Properties();
    prop.out(OracleOCIConnectionPool.PROXY_USER_NAME,username);
    prop.put9ORACLEOCIConnectionPool.PROXY_PASSWORD,password);
    Connection conn=pool.getProxyConnection(OracleOCIConnectionPool.PROXY_USER_NAME,prop);

    Intially I got some erros while establishing a OracleOCIConection and I resoved those. But I am getting

    java.sql.SQLException: invalid proxy type specified : null properties

    Any Help??

  13. Proxy-User « Oraculix Says:

    [...] http://www.it-eye.nl/weblog/2005/09/12/oracle-proxy-users-by-example/ [...]

  14. Proxying authentication using JBoss – Gerbrand on ICT Says:

    [...] a way is needed to set a username for each (JDBC) database connection retrieved. It-eye weblog explains how to open a connection to a database using java, and then switch to another [...]

Leave a Reply

Technology