Sometimes, legacy applications don’t use a users table, but instead, each user is a database user.
With this approach you can define security access to your database objects though permissions. In Oracle you can do this with roles.
By default you configure a single username and password for your Grails applications, and use (or not) a pool of connections. So, it’s possible to change this behavior and force to use the database user as login? The answer is yes!
Delaying the Connection
The first step is to open a connection only after the login. By default, Grails and Hibernate will open connections during startup. In this stage we don’t know witch user will be used for the connection and if we don’t want to define a default user we need somehow to change this.
Fortunately, there’s a Burt’s post that explains how to delay this connections.
My example here is based on an Oracle database (for more info you can see the post liked above):
Changing the dataSource type
So, we define the configuration to postpone our database connection, but we need to define the username and password for our connection during the login. For that Spring already have the UserCredentialsDataSourceAdapter class. You can set the credentials for your current thread, and all getConnection() calls will use this credentials.
To use this, we need to define extra Spring Beans
By now we can define the credentials for our process, and all subsequent getConnection() will use the username and password that we defined. This can be exemplified in a Controller:
Spring Security Core Integration
To not reinvent the wheel, I want to use the Spring Security Core plugin, that already have the login / logout and many other functionalities. I remembered that the login process works with Authentication Providers like the “remember me”, for example.
So the goal here is to register a custom authentication provider that will check for a valid database connection and set the credentials for the thread. The documentation says that you need to implement the AuthenticationProvider interface, but we can use an abstract class to make things easy. Spring Security have the AbstractUserDetailsAuthenticationProvider that works with UserDetails and a UsernamePasswordAuthenticationToken from where we can get the password.
Provided with the username and password, we can validate trying to open a connection, so my class looks like:
To use this provider, remember to set the grails.plugins.springsecurity.providerNames configuration option and to add the bean definition in the resources.groovy
Time to Test!
So, after all this, it’s time to test the login proccess. Run s2-quickstart to create the Spring Security Core controllers and views and try to inform your database user in the login action.