Grails spring-security static rules for rest resou

2020-03-03 05:58发布

问题:

I have an Grails (2.0.4) application using Spring Security plugin (version 1.2.7.3) and the secured annotation approach (the default one, more here).

Now, I have these URLs in UrlMapping.groovy with the resource key or the controller/action pair, like this:

"/$controller/$action?/$id?" {
        constraints {
            // apply constraints here
        }
    }

// other rules, all working properly

"/api/item/$id?"(resource: 'itemRest')
'/api/item/batch-delete'(controller: 'itemRest', action: 'batchDelete')

The RESTful mapping works perfectly with ItemRestController: every method (show, update, save, delete) is correctly mapped with the proper HTTP method. And the extra method (batchDelete) works as well.

I secured the API url, doing this:

grails.plugins.springsecurity.controllerAnnotations.staticRules = [
     // ...
     '/something/**': ['IS_AUTHENTICATED_FULLY']
     '/api/**': ['IS_AUTHENTICATED_FULLY']
]

Now, I get redirected to the login page if I call:

http://host/context/something/bla_bla

But not if I call (with the proper payload, when required):

http://host/context/api/item/batchDelete
http://host/context/api/item/1
http://host/context/api/item

My suspect is that the static rules are not working properly when mapping the rest controller with the resource key.

Please also note that the "something" url is not present in the UrlMapping.groovy file.

Any ideas?

回答1:

I think you have to use

grails.plugins.springsecurity.controllerAnnotations.staticRules = [
     '/itemrest/**': ['IS_AUTHENTICATED_FULLY'],
      //this will be redundant after the above rule I guess
     '/api/**': ['IS_AUTHENTICATED_FULLY']
]

Urls which are not mapped in urlMapping has to refer the controller directly in the rules. Have a look at the warning under controllerAnnotations.staticRules in the docs.

When mapping URLs for controllers that are mapped in UrlMappings.groovy, you need to secure the un-url-mapped URLs. For example if you have a FooBarController that you map to /foo/bar/$action, you must register that in controllerAnnotations.staticRules as /foobar/**. This is different than the mapping you would use for the other two approaches and is necessary because controllerAnnotations.staticRules entries are treated as if they were annotations on the corresponding controller.