In many Java EE applications declarative security is required where user and group information is stored in a database. To support this, an application server must support a security realm based on a JDBC datasource.
Glassfish V2 application server also supports a configuration like this through the JDBCRealm. Unfortunately, this JDBCRealm is restrictive in various ways:
* It assumes a data model where groups are modeled as value objects in the sense of Eric Evan's terminology in Domain Driven Design. Specifically, if a group should have more properties apart from its name, then this should be modeled in a different database structure with the group name as a key.
* A very specific datamodel is assumed. Two tables are used: One with for every user the encoded password and another with pairs of usernames and groupnames to define to which groups a user belongs.
* It is static in that it assumes that a user will always be a part of the same groups over time. After retrieving the groups for the first time, it caches them indefinitely. This makes the JDBCRealm of glassfish unsuitable for dynamic applications where users can join or leave groups.
As is clear, the JDBCRealm of glassfish either fits your purpose and you are done, or it doesn't and you have to either work around it in your application or create a separate more flexible JDBC security realm yourself. Since I had a stable application that I wasn't intending on modifying, I decided to do the latter.
The FlexibleJdbcRealm is a JDBC security realm which is similar to the approach used in JBoss application server. Instead of depending on a fixed database structure with only limited configuration, it is configured with two queries instead:
* One query for determining the (encoded) password of the user based on the user name.
* One query for determining the groups the user belongs to based on the user name.
In other words, instead of assuming a certain type of data model with configuration of some column and table names and constructing the two JDBC queries for passwords and groups as JDBCRealm does, the FlexibleJDBCRealm is configured with the two queries. As a result, FlexiblJDBCRealm is more general than JDBCRealm since it can handle any datamodel that JDBCRealm can.
In particular, in the application that triggered this, I had a datamodel that did not fit the one assumed by JDBCRealm. In my design I am using surrogate keys and have three tables:
* a Users table with primary key, user name, encoded password, and other user attributes
* a groups table with primary key, group name, and other group attributes
* a user_groups table with a mapping of users to groups (based on primary key)
This datamodel can easily be handled using FlexibleJdbcRealm but would have required a redesign of the application if I would have used JDBCRealm.