Bruno Krebs
Bruno Krebs

Reputation: 3159

Grails - spring security with basic auth only

I'm trying to create a simple app, a proof of concept actually, where my end user will interact with the server only through RESTful services. My user interface will use angularjs to send ajax requests to these services and then render the response in the browser.

In order to create a security layer I'm trying to configure spring security plugin, but there is a issue with my configuration. In this very moment, this is my config:

grails.plugin.springsecurity.userLookup.userDomainClassName = 'mymoney.Subject'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'mymoney.SubjectRole'
grails.plugin.springsecurity.authority.className = 'mymoney.Role'

grails.plugin.springsecurity.useBasicAuth = true
grails.plugin.springsecurity.basic.realmName = "Restricted Access"

grails.plugin.springsecurity.controllerAnnotations.staticRules = [
    '/**': ['permitAll']
]

grails.plugins.springsecurity.filterChain.chainMap = [
    '/rest/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
    '/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
]

If I keep my config like that, everything is available to everyone, even the /rest/** resources. My guess is that the staticRules before the chainMap is messing with everything. But the problem is that if I remove it, then everything falls under my basic auth...

So what I really want is that every resource under /rest/** would be secured by basic auth, and my SPA (single page application), that is accessible in the root context ('/') would be available to every one without any auth...

What am I missing here?

Upvotes: 1

Views: 1605

Answers (2)

thewidgetsmith
thewidgetsmith

Reputation: 194

Just to elaborate on Burt's correct answer, you can find everything you need to know in the docs for the plugin.

To get you started though, the "permitAll" expression essentially makes the corresponding URL publicly accessible. In this case the "/**" URL is the corresponding URL and it corresponds to every possible URL under the domain. So, your staticRules configuration makes your entire application publicly accessible.

The solution is to only specify the "permitAll" expression on publicly accessible resources ('//images/', '/login/', etc) and then specify an alternate expression on the secured URLs ('/admin/*', etc.).

The "permitAll" expression is a member of the Spring Expression Language (SpEL). There is a table with many SpEL expressions at the bottom of the document that I linked. Using SpEL you can configure all sorts of access rules for your application. For example:

grails.plugin.springsecurity.controllerAnnotations.staticRules = [
   '/**/images/**': ['permitAll'],        // publicly accessible images directory
   '/register': ['isAnonymous()'],        // has to be anonymous to register
   '/profile/**': ['isAuthenticated()'],  // has to be authenticated
   '/lounge/**': ['ROLE_USER', 'ROLE_ADMIN'],  // has user or admin role
   '/admin/**': ['ROLE_ADMIN']            // has to be an administrator
]

Many more options are possible and the docs are a great resource for information.

Upvotes: 1

Burt Beckwith
Burt Beckwith

Reputation: 75681

It doesn't matter how the urls are partitioned in the filter chain if you have /**=permitAll - you're not blocking anything. You need to split up the access rules also, something like

grails.plugin.springsecurity.controllerAnnotations.staticRules = [
   '/rest/**': ['ROLE_ADMIN'],
   '/**': ['permitAll']
]

Upvotes: 4

Related Questions