views:

51

answers:

3

Hi, Im working on a legacy grails application.

I have a couple of tables like this

User ( id, name,enterprise_id)

Enterprise (id, name)

Asset (id,description, enterprise_id)

I want to validate that when a certain user wants to access an asset, it has the right enterprise_id (i.e That the user belongs to the same enterprise as the asset).

For example, consider

John, a user from Microsoft, and Charles (from Oracle), only Charles should be able to access the Java Virtual Machine.

Enterprise
id,name
--------
1 Oracle
2 Microsoft

Asset
id,description,enterprise_id
----------------------------
1 Java VM     1
2 .NET        2

User
id name    enterprise_id
----------------------
1  John     2
2  Charles  1

I've been reading on spring security, but it doesn't look that it can help me. All I see is user authentication, passwords, roles, etc (Of course, I could be wrong). These things are alredy secured and working ok. For the moment i'm considering filters, but can't make them work and rolling my own security(see this question), which doesn't seem right.

Any thoughts? Is Spring Security the way to go? Shiro?

Thanks in advance

+3  A: 

You could implement this with spring-security-acl (which depends on spring-security-core)

Otherwise you could implement a 2 phase approach (Authentication + Authorization) with a set of Object-level authorization filters.

Colin Harrington
I think that filters is the way to go, since I cant see how to customize the @PreXYZ annotations to access my database tables and check for permissions. Thanks
Tom
+1  A: 

I'm using the Hibernate Filter plugin for this. There is also the MultiTenant plugin and its companion the Falcone plugin.

What these do is basically adding constraints to all DB queries, to do just what I think you are aiming for. A typical solution for you (with Hibernate Filter) would be to add this to the Asset domain (change filter name for each new domain)...

static hibernateFilters = {
  assetEnterpriseFilter(condition: ':enterpriseId=enterprise_id', types: 'integer', default: true)
}

...and extract the HibernateFilterFilters from the plugin to override like this (setting the session variable as a parameter)...

class HibernateFilterFilters {

    def filters = {
        all(controller:'*', action:'*') {
            before = {
                    def hibernateSession = grailsApplication.mainContext.sessionFactory.currentSession
                    DefaultHibernateFiltersHolder.defaultFilters.each {name ->
                        hibernateSession.enableFilter(name).setParameter('enterpriseId', session?.enterpriseId ? session.enterpriseId.toInteger() : new Integer(0))
                    }
            }

            after = {

            }
            afterView = {

            }
        }
    }

}

...and make sure not to use enterprise_id = 0 in the DB.

wwwclaes
A: 

Hi Tom,

Apache Shiro has access control built-in, and there is a grails plugin for it as well.

Authentication is the act of proving that someone is who they say they are - i.e. logging in to an application. Authorization is the process of controlling access to certain data or application features (controlling 'who' can do 'what').

Shiro has both of these concepts built in to its API and does them quite well - you can even control access to individual instances (for example, 'view' the 'user' with id 12345, etc). I highly recommend looking at the Grails plugin for Shiro as well as Shiro's distribution - it includes a few sample web applications (with and without Spring), and you can see how to use its access control - either with servlet filters for URL-based resource control or via annotations to protect individual methods.

HTH,

Les

Les Hazlewood