Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating the Proxy fails if Grails-Service is in a plugin #21

Open
yvesf opened this issue Mar 17, 2016 · 2 comments
Open

Creating the Proxy fails if Grails-Service is in a plugin #21

yvesf opened this issue Mar 17, 2016 · 2 comments

Comments

@yvesf
Copy link

yvesf commented Mar 17, 2016

In AclAutoProxyCreator#afterPropertiesSet a list of beanNames is collected from the service class names.

This list is later used to decide about creating a proxy for this bean in getAdvicesAndAdvisorsForBean.

The name matching fails for all services that are not declared directly in the project but in a grails plugin.
See ServicesGrailsPlugin line 62: If the service class is defined in a plugin then the plugin-name is prepended to the bean name.
Finally the names won't match. To me it looks like it could be corrected by employing the same logic as in the ServicesGrailsPlugin for the naming beans when creating the beanNames list.

In consequence of this problem annotations such as @PreAuthorize are just ignored on these services (depending on your code it can have an impact on application security).

In my particular use-case I'll refactor to not use annotations in the plugin, so I leave this github-issue here just as a hint for others.

@gelleouet
Copy link

To bypass this bug, you can declare your own MyAclAutoProxyCreator extends AclAutoProxyCreator and only override afterPropertiesSet method :

@Override
    void afterPropertiesSet() {
        for (GrailsClass serviceClass in grailsApplication.getArtefacts(ServiceArtefactHandler.TYPE)) {
            // old instruction bug
            //String beanName = GrailsNameUtils.getPropertyNameRepresentation(serviceClass.clazz.name)

            // new instruction
            // copy from @see org.grails.plugins.services.ServicesGrailsPlugin
            String beanName = null
            GrailsPlugin providingPlugin = pluginManager.getPluginForClass(serviceClass.getClazz())

            if (providingPlugin && !serviceClass.shortName.toLowerCase().startsWith(providingPlugin.name.toLowerCase())) {
                beanName = "${providingPlugin.name}${serviceClass.shortName}"
            } else {
                beanName = serviceClass.propertyName
            }

            if (shouldProxy(serviceClass.clazz, beanName)) {
                serviceBeanNames << beanName
            }
        }
    }

To finish and use your bean, just overload ACL bean name in Spring beans declarations (or a doWithSpring() plugin) with

securedBeansInterceptor(MyAclAutoProxyCreator) {
  grailsApplication = grailsApplication
  pluginManager = pluginManager
  interceptorNames = ['methodSecurityInterceptor']
  proxyTargetClass = true
}

Note that you have to inject a pluginManager bean.

With this method, you can continue to use ACL annotations without refactoring your code and without big changes

@puneetbehl
Copy link

@gelleouet Would you be interested in sending a PR with this change?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants