We have an application that needs to access a database that is owned by a different team. That database has security inside the database (triggers, table permissions, etc) and so we need to establish a connection to the database using the same username/password that connected to our EJB.
We're running on JBoss 5.1. Standard Java EE solutions are preferred, but JBoss specific answers will do.
At the moment our solution is
- Create a datasource in JBoss with no user-id password
- Require the client to pass their username/password into the EJB (the EJB is a stateful session bean (SFSB), and remembers the username/password)
- The session bean creates a new connection using
DataSource.getConnection(String, String)
- The connection is "created" from the datasource at the start of each request (The datasource implementation might reuse an existing connection)
The main problem we have is connection pooling.
The JBoss co开发者_StackOverflow中文版nnection pool doesn't manage separate pools for each username - they're all thrown into 1 big pool, and the username is checked after the object is retrieved from the pool (inside InternalManagedConnectionPool
).
If the usernames don't match, then the connection is removed from the pool & destroyed.
This means that as soon as we have 2 users, there's a 50% chance that any connection that is put into the pool will be destroyed when it is next accessed. And as we increase the number of users, those odds get a lot worse.
We can't simply create 1 connection in the SFSB and retain it because JBoss is too smart for us, and it detects that we've left a connection open and automatically returns it to the pool for us, so the next request to the SFSB will fail with a "not associated" connection.
It would also be nice if we could simply get JBoss to create a connection as "the currently logged in user", but the solution we have is bearable.
My googling has failed to find any recommended patterns for doing this sort of thing. Everyone seems to assume that you want your datasource to use a single user for all connections (which is nice when it's possible, but I can't do that in this case)
The only solutions I can some up with are
- Don't use a container provided datasource. Put the JDBC URL into a configuration value somewhere and create connections myself (possibly with the help of spring)
- Bind a different Datasource implementation (possibly a custom one) into JNDI
Has anyone got any better solutions? Or pointers to recommended practices in this area?
(The database is Sybase ASE 15, but I doubt that makes any difference to the solution)
A bit more reading of the documentation has led me to what appears to be the solution.
Adding
<application-managed-security/>
into my datasource file seems to have fixed the problem of pooling the connections.
I'm not sure how I missed that the first time around.
精彩评论