Freitag, Dezember 09, 2005
J2EE - Oracle Enterprise Users Security
Oracle Enterprise Users Security make it possible to combine SSO, JAAS, JDBC-Connection Pooling (J2EE-DataSouce) and VPD (Row Level Security) in conjunction with Proxy Authentication and single stored LDAP Users/Roles.
Depending of the securit requirements and used product or feature stack, many different configurations possible. Following I will demonstrate the scenario how to use Oracle Enterprise Users Security with connection pooling in an Java EE environment.
Suppose you have 3 user types:
1. Enterprise User: The LDAP users which connect to the DB without any DB resources (No DB create user command is required!)
2. Global Schema User: The DB-Schema how the enterprise user is automaticly mapped to.
3. JDBC Pool User: The user used to create the connection pool with only connect rights. That user has no resource or other permissons.
Required steps:
1. Create the LDAP V3 User Structure with any LDAP Tool or command
2. Use the Oracle Enterprise Security Manager and Map the LDAP Roles to DB Roles
3. create the oracle pool user: create jdbcpooluser identified by MyPassword123
4. grant connect to jdbcpooluser
5. Permit the Global-Schema user to connect through the jdbc pool user: alter user global_schema grant connect through jdbcpooluser
6. On each connect swich the jdbc connection from the pool to the LDAP user:
properties.put(oraConnection.PROXY_DISTINGUISHED_NAME, username);
oraConnection.openProxySession(OracleConnection.PROXYTYPE_DISTINGUISHED_NAME,´properties);
Within Springframwork you can overwrite the doGetConnection methode of UserCredentialsDataSourceAdapter class to get the connection hook before Sring makes any DB access.
To establish this inside a JSF-Application you must overwrite the SpringPhaseListener to bound the principal to the current Thread:
FacesContext fc = FacesContext.getCurrentInstance().getExternalContext().
Principal j2eePrincipal = fc.getUserPrincipal(); // Bound the context to the current thread with your helper class in usage of the InheritableThreadLocal static variable BmaierContextHolder.createContext(j2eePrincipal);
Afterward you should overwrite the methode doGetConnection of UserCredentialsDataSourceAdapter class as followed:
protected Connection doGetConnection(String username, String password) throws SQLException {
...
Connection connection = getTargetDataSource().getConnection(username, password); ...
if(connection instanceof oracle.jdbc.OracleConnection){ BmaierSecurityContext sc = BmaierSecurityContextHolder.getNgcmSecurityContext();
username = sc.getPrincipal().getName();
// we grant DB-proxy without explicit password delivery - make SSO possible!
password = "";
OracleConnection oc = (OracleConnection)connection;
properties.put(oraConnection.PROXY_DISTINGUISHED_NAME, username);
oraConnection.openProxySession(OracleConnection.PROXYTYPE_DISTINGUISHED_NAME, properties);
return oraConnection;
}
This make it possible to use J2EE/JAAS-Authentication in conjunction with secured and pooled database connections.
Depending of the securit requirements and used product or feature stack, many different configurations possible. Following I will demonstrate the scenario how to use Oracle Enterprise Users Security with connection pooling in an Java EE environment.
Suppose you have 3 user types:
1. Enterprise User: The LDAP users which connect to the DB without any DB resources (No DB create user command is required!)
2. Global Schema User: The DB-Schema how the enterprise user is automaticly mapped to.
3. JDBC Pool User: The user used to create the connection pool with only connect rights. That user has no resource or other permissons.
Required steps:
1. Create the LDAP V3 User Structure with any LDAP Tool or command
2. Use the Oracle Enterprise Security Manager and Map the LDAP Roles to DB Roles
3. create the oracle pool user: create jdbcpooluser identified by MyPassword123
4. grant connect to jdbcpooluser
5. Permit the Global-Schema user to connect through the jdbc pool user: alter user global_schema grant connect through jdbcpooluser
6. On each connect swich the jdbc connection from the pool to the LDAP user:
properties.put(oraConnection.PROXY_DISTINGUISHED_NAME, username);
oraConnection.openProxySession(OracleConnection.PROXYTYPE_DISTINGUISHED_NAME,´properties);
Within Springframwork you can overwrite the doGetConnection methode of UserCredentialsDataSourceAdapter class to get the connection hook before Sring makes any DB access.
To establish this inside a JSF-Application you must overwrite the SpringPhaseListener to bound the principal to the current Thread:
FacesContext fc = FacesContext.getCurrentInstance().getExternalContext().
Principal j2eePrincipal = fc.getUserPrincipal(); // Bound the context to the current thread with your helper class in usage of the InheritableThreadLocal static variable BmaierContextHolder.createContext(j2eePrincipal);
Afterward you should overwrite the methode doGetConnection of UserCredentialsDataSourceAdapter class as followed:
protected Connection doGetConnection(String username, String password) throws SQLException {
...
Connection connection = getTargetDataSource().getConnection(username, password); ...
if(connection instanceof oracle.jdbc.OracleConnection){ BmaierSecurityContext sc = BmaierSecurityContextHolder.getNgcmSecurityContext();
username = sc.getPrincipal().getName();
// we grant DB-proxy without explicit password delivery - make SSO possible!
password = "";
OracleConnection oc = (OracleConnection)connection;
properties.put(oraConnection.PROXY_DISTINGUISHED_NAME, username);
oraConnection.openProxySession(OracleConnection.PROXYTYPE_DISTINGUISHED_NAME, properties);
return oraConnection;
}
This make it possible to use J2EE/JAAS-Authentication in conjunction with secured and pooled database connections.