I am trying to implement row level security so our application can enforce more stringent access control.
One of the technologies we are looking into is Oracle's Virtual Private Database, which allows row level security by basically augmenting all queries against specific tables with a where clause predicate. Since we are in a web environment, we need to set up a special context within Oracle, inside a single request's thread. We use connection pooling with a service account.
I started to look into Eclipse Link and Hibernate. Eclipse Link seems to have events that fit perfectly into this model.
This would involve us migrating from hibernate, which is not a problem, but we would then be bound to EL for these events.
Oracle seems to imply that they implement at the data source level in Web Logic product.
The context is set and cleared by the WebLogic data source code.
Question: Is it more appropriate to do this at the DataSource level with some series of events. What are the events or methods that I should pay the most attention too?
Added Question: How would I extend a connection pool to safely initialize an oracle context with some custom data? I am digging around in Apache, and it seems like extending BasicDataSource doesn't give me access to anything that would allow me to clean up the connection when Spring is done with it.
I need to set up a connection, and clean up a connection as the exit / enter the connection pool. I am hoping for an implementation that is so simple, no one can mess it up by breaking some delicate balance of products.
- Specifically we are currently using Apache Commons DBCP Basic Data Source
This would allow us to use various ways to connect to the database and still have our security enforced. But I don't see a great example or set of events to work with, and rolling my own security life cycle is never a good idea.
I eventually solved my problem by extending some of the Apache components.
First I extended org.apache.commons.pool.impl.GenericObjectPool and overrode both borrowObject() and returnObject(). I knew the type of the objects in the pool (java.sql.Connection) so I could safely cast and work with them.
Since for my case I was using Oracle VPD, I was able to set information in the Application context. I recommend you read about that in more depth. It is a little complicated and there are a lot of different options to hide or share data at various contexts level, and across RAC nodes. Start
In essence what I did was generate a nonce and use it to instantiate a session within oracle, and then set the access level of the user to a variable in that session, that the Oracle VPD policy would then read and use to do the row level filtering.
I instantiated and destroyed that information in my overridden borrowObject() and returnObject() The SQL I ran was something like this:
CallableStatement callStat =
conn.prepareCall("{call namespace.cust_ctx_pkg.set_session_id(" + Math.random() + ")}");
callStat.execute();
Note math.random() isn't a good nonce.
Next was to simply extend org.apache.commons.dbcp.BasicDataSource and set my object pool by overriding createConnectionPool(). Note that the way I did this disabled some functionality I did not need, so you may need to rewrite more or less than I did.
You can try any object level security mechanism for simplicity, like Spring Security ACL.
You will want to do this at the application layer. You will want a pre-commit hook and a post read hook.
The pre-commit hook is used to ensure that data from the client is being presented by a user authorized to modify that data. This prevents an unauthorized user from overwriting data that they shouldn't be able to access.
It's not intuitive, but the post read hook is used to keep the client from accessing data the user shouldn't be allowed to view. This happens post-view because this is being enforced at the application layer, not at the data layer. The application has no way to know if the caller is allowed to access the data until it's been retrieved from the data layer. In the post read hook you evaluate the credential on each row returned against the credential of the logged in user in order to determine whether or not access is allowed. If access is denied on any row then an exception would be raised and the data would not be returned to the client.
Application level security done in this way requires that you have a way to connect each row in a table to a permission/role required to access it and a way to evaluate a user's permissions on the server at runtime.
Hope that helps.
You will get better control by using one of the other Commons DBCP Datasources.
The Basic one is just that: basic :)
The ones in org.apache.commons.dbcp.datasources package gives you more fine-grained control.
Related
I am unable to configure/change the Map(declared as part of hazelcast config in spring) properties after hazelcast instance start up. I am using hazelcast integrated with spring as hibernate second level cache. I am trying to configure the properties of map (like TTL) in an init method (PostConstruct annotated) which is called during spring bean initialization.
There is not enough Documentation , if there is please guide me to it.
Mean while i went through this post and found this Hazelcast MapStoreConfig ignored
But how does the management center changes the config, will it recreate a new instance again ?
Is hazelcast Instance light weight unlike session factory ? i assume not,
please share your thoughts
This is not yet supported. JCache is the only on-the-fly configuration data structure at the moment.
However you'll most probably be able to destroy a proxy (DistributedObject like IMap, IQueue, ...), reconfigure it and recreate it. Anyhow at the time of recreation you must make sure that every node sees the same configuration, for example by storing the configuration itself inside an IMap or something like that. You'll have to do some wrapping on your own.
PS: This is not officially supported and an implementation detail that might change at later versions!
PPS: This feature is on the roadmap for quite some time but didn't made it into a release version yet, it however is still expected to have full support at some time in the future.
I'm writing a web app that supports multiple users. Each user has their own database - using H2. all database schemas are the same.
I wish to use Spring + Hibernate for this application.
So I'm stuck at how to associate a user's database with that user - maybe associated it in the HTTPSession, and extend spring's AbstractRoutingDataSource? but wouldn't this effect Hibernate's cache? Another way is to have a SessionFactory with each datasource, even though every datasource's schema is the same... so I see that as a waste.
Anyways selecting the datasource needs to be dynamic - they can't be pre-configured in context files, as each new user will have its own database created. Is there any existing frameworks/solutions?
I don't know too much about Hibernate Shards, maybe that works?
I might be wrong about the (strict) need to have one SessionFactory per database, as suggested by some resources:
Dynamic DataSource Routing
I'll take some time to re-read everything tomorrow (I didn't get all the details to be honest) and to fully understand the implications of such a setup (although it seems clear that it will break the second-level cache). I'll come back on this later.
I'm writing a web app that supports multiple users. Each user has their own database - using H2. all database schemas are the same.
I wonder how this will scale... How many users do you have? How do you run H2, what mode?
So I'm stuck at how to associate a user's database with that user - maybe associated it in the HTTPSession, and extend spring's AbstractRoutingDataSource?
You'll have to build a SessionFactory per user and associate it to the logged user (in a Map, using the login as key) and then obtain a Session from a given SessionFactory. Binding the lifecycle of the SessionFactory to the HTTP session seems to be a good idea (to save some memory) but I am not sure Spring will be very helpful here. I might be wrong but a variation of the HibernateUtil class and a fully programmatic approach looks easier. I'm not sure you'll need multiple connections per user by the way.
but wouldn't this effect Hibernate's cache?
What cache?
Another way is to have a SessionFactory with each datasource, even though every datasource's schema is the same... so I see that as a waste.
Oh, it's a waste, but that's what you want to do (one database per user). And you don't have the choice (you need one SessionFactory per datadabase). Why do you need one database per user actually? Are you sure this is a wise decision? As already hinted, this means much troubles, won't scale well, adds complexity, etc. Why not using a single database and associating data to the user?
Anyways selecting the datasource needs to be dynamic - they can't be pre-configured in context files, as each new user will have its own database created. Is there any existing frameworks/solutions?
Not to my knowledge. Which is also why I think you'll have to do everything programatically.
I don't know too much about Hibernate Shards, maybe that works?
Given the dynamic needs of your application, I don't see how it could help.
This may help you:
Dynamic Datasource via Spring using HotSwappableTargetSource
Hibernate + Spring using multiple datasources?
Thanks to the help from the 2 people (Pascal and org.life.java)!
It is possible, but with some problems: e.g. the hibernate 2nd level cache/query cache.
This link supplied by Pascal is a very good resource:
http://www.jroller.com/kenwdelong/entry/horizontal_database_partitioning_with_spring.
My main motivation for giving each user a separate database is because the data is likely to grow rapidly, thus horizontal partitioning is required.
I am looking for a security framework for Java web application with Object granularity.
What it means is that I don't just want to filter by urls or by roles, but by specific user ownership of domain objects inside the system.
For example, if there is a Message object that has a Sender user and a Receiver user I would like to be able to configure it so that every Message can be RW by its sender and RO by its receiver.
Or for example, all user profiles are viewable by all users but editable only by the owner.
This rules, of course, I would like to define them with meta data (annotations, xml files, whatever) and not embedded in my business logic.
Is there such a beast out there? Preferably open source.
Spring Security can provide things like method security and "secure objects" using AOP.
You're looking for access control lists (ACLs). Like the other respondents I think Spring Security is worth checking out here--Acegi is just what Spring Security used to be called before they renamed it. Spring Security does have explicit support for ACLs (in addition to URL-based, role-based and group-based access controls). It supports both XML and annotation-based configuration. And you can apply ACL filtering to the view (using taglibs to decide what to render or suppress in the JSP), to methods that return a single domain object (decide whether to allow the method call to succeed), and to methods that return a collection (decide which objects to filter out of the collection before returning it).
You might be able to get away with rolling your own ACL code for simple requirements, but in my opinion ACLs can get tricky pretty quickly. Especially if you have lots of domain objects and you have to start taking performance management seriously.
Check out this link Acegi Security Fundementals - it's slightly outdated but still gives you the main concepts of Spring Security's object level authorization mechanisms.
I have an application - more like a utility - that sits in a corner and updates two different databases periodically.
It is a little standalone app that has been built with a Spring Application Context. The context has two Hibernate Session Factories configured in it, in turn using Commons DBCP data sources configured in Spring.
Currently there is no transaction management, but I would like to add some. The update to one database depends on a successful update to the other.
The app does not sit in a Java EE container - it is bootstrapped by a static launcher class called from a shell script. The launcher class instantiates the Application Context and then invokes a method on one of its beans.
What is the 'best' way to put transactionality around the database updates?
I will leave the definition of 'best' to you, but I think it should be some function of 'easy to set up', 'easy to configure', 'inexpensive', and 'easy to package and redistribute'. Naturally FOSS would be good.
The best way to distribute transactions over more than one database is: Don't.
Some people will point you to XA but XA (or Two Phase Commit) is a lie (or marketese).
Imagine: After the first phase have told the XA manager that it can send the final commit, the network connection to one of the databases fails. Now what? Timeout? That would leave the other database corrupt. Rollback? Two problems: You can't roll back a commit and how do you know what happened to the second database? Maybe the network connection failed after it successfully committed the data and only the "success" message was lost?
The best way is to copy the data in a single place. Use a scheme which allows you to abort the copy and continue it at any time (for example, ignore data which you already have or order the select by ID and request only records > MAX(ID) of your copy). Protect this with a transaction. This is not a problem since you're only reading data from the source, so when the transaction fails for any reason, you can ignore the source database. Therefore, this is a plain old single source transaction.
After you have copied the data, process it locally.
Setup a transaction manager in your context. Spring docs have examples, and it is very simple. Then when you want to execute a transaction:
try {
TransactionTemplate tt = new TransactionTemplate(txManager);
tt.execute(new TransactionCallbackWithoutResult(){
protected void doInTransactionWithoutResult(
TransactionStatus status) {
updateDb1();
updateDb2();
}
} catch (TransactionException ex) {
// handle
}
For more examples, and information perhaps look at this:
XA transactions using Spring
When you say "two different databases", do you mean different database servers, or two different schemas within the same DB server?
If the former, then if you want full transactionality, then you need the XA transaction API, which provides full two-phase commit. But more importantly, you also need a transaction coordinator/monitor which manages transaction propagation between the different database systems. This is part of JavaEE spec, and a pretty rarefied part of it at that. The TX coordinator itself is a complex piece of software. Your application software (via Spring, if you so wish) talks to the coordinator.
If, however, you just mean two databases within the same DB server, then vanilla JDBC transactions should work just fine, just perform your operations against both databases within a single transaction.
In this case you would need a Transaction Monitor (server supporting XA protocol) and make sure your databases supports XA also. Most (all?) J2EE servers comes with Transaction Monitor built in. If your code is running not in J2EE server then there are bunch of standalone alternatives - Atomicos, Bitronix, etc.
You could try Spring ChainedTransactionManager - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html that supports distributed db transaction. This could be a better alternative to XA
I'm writing an application which has to be configurable to connect to Oracle, SQL Server and MySQL depending on client whim.
Up till now I'd been planning on using the JDBC-ODBC bridge and just connecting to the databases using different connection strings.
I'm told this is not very efficient.
Is there a pattern or best practice for connecting to multiple database systems? Or for selecting which driver to use?
Should I have it configurable? but include all three drivers or build three separate clients?
I'm not doing anything complex just pumping (inserting) data into the database from an event stream.
I would suggest that you make it configurable and include the three drivers. You can use a pattern like this: Create a super class (lets call it DAO) that provides the functionality of connecting to the database. This could be abstract.
Create a concrete sub class for each type of database that you wish to connect to. So you may end up with MySQLDAO, MSSQLDAO, and OracleDAO. each one will load the respective driver and use its respective connection string.
Create another class (lets call it DAOFactory) with a method getDAO(DB) that will create an instance of the DAO depending on the value of DB.
So for instance(in Pseudocode):
if(DB.equals("MySQL")){
DAO = new MySQLDAO();
}
return DAO;
So any code that needs to connect to the database will call the DAOFactory and ask for a DAO instance. You may store the DB value in an external file (like a properties file) so that you do not have to modify code to change the type of database.
this way your code does not need to know which type of database it is connecting to, and if you decide to support a fourth type of database later you will have to add one more class and modify the DAOFactory, not the rest of your code.
If you need anything complex, Hibernate is a good choice.
otherwise, what I would do is store your connection details in a properties file (or some other form of configuration) - namely: driver classname, JDBC url, username and password.
Then, all you need to do is load up the connection details from your properties file and include the correct JAR file on your classpath and you're done.
You could use a library such as Commons-DBCP if you wanted it to be a little easier to configure but other than that it's all you need to do (provided your SQL statements work on every database, of course).
If you're careful (and you test), you can do this with straight JDBC and just vary the driver class and connection information. You definitely want to stay away from the JDBC-ODBC bridge as it's generally slow and unreliable. The bridge is more likely to behave differently across dbs than JDBC is.
I think the DAO path is overkill if your requirements are as simple as listed.
If you're doing a lot of inserts, you might want to investigate prepared statements and batched updates as they are far more efficient. This might end up being less portable - hard to say without testing.
Take a look at Datasource. This is the preferred mechanism for obtaining a database connection.
IMO this provides an adminstrator the greatest flexibility for choosing database, connection pooling, and transaction strategies.
If you're using tomcat, then see here for how to register a Datasource with tomcat's JNDI.
If you're using Spring, then you can obtain a Datasource using jee:jndi-lookup.
If you're using Spring, but don't want to use JNDI, take a look at DriverManagerDataSource for a discussion of how to obtain a pooled Datasource (DBCP or C3P0).