Having multiple sessionFactory instances - oracle

I am porting a legacy application to hibernate 5 and I'm having trouble with the login phase. Here's how it works (I can't change that):
user initially connects to oracle DB with a generic login/password (same for all users)
then user runs a "login" stored procedure and enters a unique password as parameter
the procedure returns a specific Oracle DB username/password to the user
user disconnects from DB and reconnects using the credentials given by the stored procedure
I currently create one instance of sessionFactory per connected user, but I'm worried that this will impact performance. Is there a better way to do this?
Thanks

Hibernate Multitenancy with "Separate database" strategy would work even if you are actually connecting to the same database but different credentials.
MultiTenantConnectionProvider must be specified to return connection with right username and password.

Related

DB User account Password Reset from oracle apex

Iam creating an app to change the password of selected Db user account.When an user select a particular db name and user of the db then click submit button i should call procedures that changes the password of the db user.So guide me how to connect to selected db from oracle Apex and do it.
As far as I can tell, there are two ways to change someone's password:
connect as that user
connect as a privileged user (such a SYS)
and run such a command:
alter user scott identified by tiger;
As you'd want to do that for any database you have a access to, as well as every user in those databases, I doubt that you know their passwords so I guess that you'll connect as a privileged user to all those databases. Of course, you have to know their passwords.
One option would be to
create the same stored procedure (which will modify someone's password) in every database
it'll accept username and its new password
as alter table is DDL, you'll have to use dynamic SQL (execute immediate)
create database links to those databases in a schema you use to connect to your Apex application
depending on database you choose, call appropriate procedure via database link and pass chosen username and its new password. This might also require some kind of dynamic SQL, if you want to use different DB link name
I don't know which database version you use, but - have a look at 11g's Accessing and Modifying Information in Multiple Databases, especially "Running a Stored Procedure in a Remote Oracle Database" chapter for more info.

Passing client userid to Oracle when using a pooled connection

Our company has an audit requirement to track individual user interaction with the application by user id. We use Tomcat 7 with the Tomcat connection pool and an Oracle 11.2 database (soon to be 12c). We connect using a Type 4 datasource managed by JNDI on the server which uses a system user id. Users log on using SSO to the web application. We want to make sure that whenever a user modifies a database record, their SSO signon id instead of the system id is used in an audit column to identify who made the modification.
My research shows that using getClientInfo and setClientInfo may be the way to go and I want to be clear on how I would implement this. Would I use the setClientInfo on the pooled datasource Connection to set the client user id, or run the Oracle stored procedure DBMS_APPLICATION_INFO.SET_CLIENT_INFO to pass the client user id? I know that in the Oracle virtual table v$session there is a column for OSUSER that holds this information. How do I get it there? Could I make a direct update to that column?
Since this is a multi-threaded application server, I don't want to end up with a concurrancy issue.

Passing ClientInfo/ClientIdentifier on syscontext/connection with Hibernate for audit purposes

I have a web service which processes inserts/updated data to DB. When client calls this webservice, UserId(currently logged in user to portal) will be sent in Request. I need to pass this userId to Db connection or set it in sys context for Audit purpose. we have existing audit tables and triggers to inserts/updates to Audit table after insert/update on actual table. So to track these changes I need to pass this UserId somehow to connection so that it can be retrieved from DB from Sys Context or $session and inserts in Audit table. I am currently using Spring and Hibernate transactions to process data with DB.
I tried to Set client info on Connection but it's not working. I tried below:
Session session=sessionFactory.getCurrentSession();
SessionImpl sImpl=(SessionImpl) session;
Connection connection=sImpl.connection();
connection.setClientInfo("ClientUser", "ABC");
And also I am trying to set client info by calling Stored procedure DBMS_APPLICATION_INFO.SET_CLIENT_INFO before performing operation on DB every time from application code.but I am not sue if it's a correct way to handle it.
I am trying it with both OCI and thin JDBC drivers but not able find a way to set this user id.
Can someone let me know if there is any efficient way to pass user id on sys context or with Connection. I am currently using hibernate4, Spring, Websphere Server, Oracle DB.
I am using Spring #Transactional to handle hibernate Connections and transactions to perform operation on DB.Connections are from Connection pool and I am using org.springframework.jndi.JndiObjectFactoryBean for dataSource.
is there any way to have interceptor or wrapper around connection to set it when we get the connection from connection pool.
Has anyone done this before?
This is described in spring data JDBC Extensions for the Oracle Database
Chapter
8.2 Configuration of a Custom DataSource Connection Preparer
...but you could implement a ConnectionPreparer that would use the current users login id. That way you can capture user login information even if your data source is configured with a shared user name.
This is a solution for oracle, which I think you are using. It should be also possible to adapt that to another database.

Prevent applications to log in on Oracle Database

Does anybody knows how could I make a trigger or anything else to prevent people to connect on my database with any kind of applications besides mine?
Note that the super-old-and-unsecure trigger to block few .exe such TOAD or watever does NOT really works, since you can just rename the EXE to MyApplication.exe.
Hints?
An easier method would be to move the security to a role that can be enabled only by your application - see a previous answer of mine here
WIth this method another application may create a session but has no other privileges since the role is not enabled.
You may wish to consider Oracle's Secure Application Roles -- it won't prevent people from logging into the database through a rogue application, but it can prevent them from accessing tables and packages if the application doesn't set the role using the password that only it knows.
You can find an tutorial on deploying it here, although to secure it, you'd have to create the role with a password, and your application would have to know the password when issuing the SET ROLE rolename IDENTIFIED BY rolepassword; statement.
I don't know that Oracle has any functionality to help with this (I could be wrong though) so the next best thing might be to write a small server app that lets you have much better control over the login process and acts as the middle-man between the client apps and the database server. That way, all connections to the database come through your server app, and you can control how your server identifies which client app is legit. This will add a bit of complexity to the system though.
If you don't trust the program name in v$session then the only options that come to mind are to have your application encode the password, so that what they type in isn't actually what's used to connect to the DB; or have your app log in with a private username/password and authenticate users against your own users table instead of having Oracle user accounts for them. Both options make management of accounts more complicated though.
When your application logs on, you call a stored procedure that associates the current oracle session as a "trusted" session. Do this by creating a trusted sessions table with a field for sessionID and trusted bit (and optionally a random hash to prevent user tampering).
Create a system wide trigger, that checks the your current session id (and random hash) to detect if it is trusted. If the session doesn't exist in the table, you don't allow the query, and log off the user.
You should also setup a shutdown trigger to clear the trusted session table on exit.

Allowing oracle db login only to specific application?

We want to allow DB access (Oracle) to our users only through our own application - let's call it "ourTool.exe", installed locally on the users computers. Currently, the users must provide username/password whenever they start "ourTool". The provided password password gets decrypted and we use username/decrypted-password to finally log in to the Oracle DB. This approach prevents the users from directly accessing our DB using third party tools (SQLplus, Excel, Access, ...) and everything in the DB is guaranteed to have been entered/edited using "ourTool".
Now, one of our clients wants to allow its users "single sign-on" (with SmartCards/Oracle PKI). With this, the user will be able connect to our DB without providing any password every time they start "ourTool". But the same will be true for the potentially dangerous tools like SQLplus, Excel, Access, etc.
Is there a way to prevent this? How can we make sure that every record in our DB is only created/edited/deleted using "ourTool" in this scenario?
Since it's your application and you have control of the source, you can use either password protected database roles or Secure Application Roles that are enabled from ourTool.exe. (see http://www.oracle.com/technology/obe/obe10gdb/security/approles/approles.htm ).
For example, with a password-protected database role, the initial connection would be with only the CREATE SESSION privilege, and then ourTool.exe would issue the SET ROLE with password known only to you. Any other application doesn't have the information to set the role. Obviously, the privileges are granted only to the role and not directly to the user in this configuration.
By default, OCI transmits the calling application EXE name and you can access it by querying v$session:
SELECT program
FROM V$SESSION
, which you can do in an AFTER LOGON trigger.
But this can be easily overriden and should not be relied upon.
I renamed my sqlplus.exe to myTool.exe and after making a connection with myTool.exe
SELECT program
FROM V$SESSION
where username = 'SYSTEM';
Returns:
myTool.exe
So be aware, as Quassnoi said: although usable in some circumstances it's certainly not bullit proof.

Resources