0

I was trying to simplify the code of security checks in my grails app and I found that there is a way to drive the security on a service class.

Some of the references I found related to that: https://www.mscharhag.com/grails/spring-security-call-bean-method-in-spel-expression Grails custom security evaluator and some others...

So I tried wiring everything in and seems pretty straightforward, but when I am configuring my custom beans into resources.groovy I am getting this error.

A component required a bean named 'parameterNameDiscoverer' that could not be found.

My resources.groovy looks like this:

import com.auth0.client.auth.AuthAPI
import grails.plugin.springsecurity.rest.RestAuthenticationProvider
import priz.auth0.Auth0APIService
import priz.auth0.Auth0TokenStorageService
import priz.auth0.Auth0TokenVerificationService
import priz.auth0.Auth0UserResolverService
import priz.security.GrailsBeanResolver
import priz.security.GrailsExpressionHandler
import priz.security.UserPasswordEncoderListener

// Place your Spring DSL code here
beans = {
    expressionHandler(GrailsExpressionHandler) {
        beanResolver = ref('beanResolver')
        parameterNameDiscoverer = ref('parameterNameDiscoverer')
        permissionEvaluator = ref('permissionEvaluator')
        roleHierarchy = ref('roleHierarchy')
        trustResolver = ref('authenticationTrustResolver')
    }

    beanResolver(GrailsBeanResolver) {
        grailsApplication = ref('grailsApplication')
    }

    userPasswordEncoderListener(UserPasswordEncoderListener)

    authApi(AuthAPI) { beanDefinition ->
        beanDefinition.constructorArgs = [
                '${priz.auth0.api.domain}',
                '${priz.auth0.api.clientId}',
                '${priz.auth0.api.clientSecret}'
        ]
    }

    auth0APIService(Auth0APIService) {
        authAPI = ref('authApi')
    }

    auth0TokenVerificationService(Auth0TokenVerificationService)

    auth0UserResolverService(Auth0UserResolverService)

    tokenStorageService(Auth0TokenStorageService) {
        jwtService = ref('jwtService')
        userDetailsService = ref('userDetailsService')
        auth0TokenVerificationService = ref('auth0TokenVerificationService')
        auth0APIService = ref('auth0APIService')
        auth0UserResolverService = ref('auth0UserResolverService')
    }

    /* restAuthenticationProvider */
    restAuthenticationProvider(RestAuthenticationProvider) {
        tokenStorageService = ref('tokenStorageService')
        useJwt = false
        jwtService = ref('jwtService')
    }

}

Of course, I don't have parameterNameDiscoverer specifically defined in the resources, but I expected that since I didn't customize any of these dependencies are already provided by the Spring Security plugins. But it seems like they cannot be found.

What am I missing? Do I need to define the entire dependency tree in resources?

Shurik Agulyansky
  • 2,607
  • 2
  • 34
  • 76
  • "What am I missing?"- Not clear. "Do I need to define the entire dependency tree in resources?" - No. What in particular do you want injected into the `parameterNameDiscoverer` property of the `priz.security.GrailsExpressionHandler` bean? – Jeff Scott Brown Nov 07 '20 at 22:24
  • All I need is a custom expression handler with a custom beam resolver. But it seems like I have to redefine all the dependencies. – Shurik Agulyansky Nov 08 '20 at 00:39
  • "But it seems like I have to redefine all the dependencies" - That really isn't the case. We support what you are doing. Is there a bean in your context with the name `parameterNameDiscoverer`? – Jeff Scott Brown Nov 08 '20 at 18:23
  • `"But it seems like I have to redefine all the dependencies."` - if that were true you would have other issues, like references to the `userDetailsService` bean, for example. – Jeff Scott Brown Nov 08 '20 at 18:24
  • @JeffScottBrown hmmm... good point. What is the easiest way to check that? – Shurik Agulyansky Nov 09 '20 at 06:21
  • Digging into it a bit deeper (into the source code of spring security), I am getting a sense that I am going in the wrong direction altogether. I'll update once I have something more concrete. – Shurik Agulyansky Nov 09 '20 at 06:48
  • `"What is the easiest way to check that?"` - I suppose you could debug the application context and in particular the instantiation of bean definitions. You could skip that if you believe me. It is definitely the case that you do not have to redefine all bean definitions but debugging will help you verify that. – Jeff Scott Brown Nov 09 '20 at 14:34
  • If you were using a plugin that provided the `parameterNameDiscoverer` bean and the you removed that plugin, of course that bean would be gone. If your `priz.security.GrailsExpressionHandler` bean depends on the `parameterNameDiscoverer`, then something will need to provide that bean, but I wouldn't call that defining the entire dependency tree in resources. – Jeff Scott Brown Nov 09 '20 at 14:36

1 Answers1

0

This should be as simple as creating the bean instance of the implementation you want by adding something like the following to your resources.groovy

parameterNameDiscoverer(DefaultSecurityParameterNameDiscoverer)

Assuming you want the default implementation that is provided with Spring Security (v3.2+). It's not clear what implementation you want, so you may browse the java docs.

Joshua Moore
  • 24,706
  • 6
  • 50
  • 73