springgrailstomcat8grails3grails-spring-security

User authentication failing after upgrading to 3.2.1


I just upgraded my app from Grails 3.2.0 to 3.2.1 due to some problems and the user authentication started failing. I'm using Grails Spring Security Core plugin version 3.1.1.

I'm getting the following exception:

org.springframework.security.authentication.InternalAuthenticationServiceException:
    Cannot cast object 'User(email:user@example.com)' with class 'com.test.User' to class 'com.test.User'
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:126)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
    at grails.plugin.springsecurity.web.authentication.GrailsUsernamePasswordAuthenticationFilter.attemptAuthentication(GrailsUsernamePasswordAuthenticationFilter.groovy:53)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)

Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException:
    Cannot cast object 'User(email:user@example.com)' with class 'com.test.User' to class 'com.test.User'
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
    at com.test.User.findWhere(User.groovy)
    at com.test.User$findWhere.call(Unknown Source)
    at grails.plugin.springsecurity.userdetails.GormUserDetailsService.$tt__loadUserByUsername(GormUserDetailsService.groovy:60)
    at grails.plugin.springsecurity.userdetails.GormUserDetailsService$_loadUserByUsername_closure1.doCall(GormUserDetailsService.groovy)

This is only failing when we deploy it on Apache Tomcat (using 8.5.6) but it is working fine on development with grails run-app.

Here are the modified dependencies in build.gradle (rest configuration is same as generated by create-app):

// "compile" changed to "provided"
provided "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails.plugins:spring-security-core:3.1.1"
compile "org.grails.plugins:asynchronous-mail:2.0.0.RC4"
compile "org.mongodb:bson:3.3.0"
compile "org.codehaus.groovy.modules.http-builder:http-builder:0.7.1"
runtime "mysql:mysql-connector-java:5.1.39"
// https://github.com/spring-projects/spring-boot/issues/6761
runtime "com.google.code.gson:gson:2.5"
// Commented this to avoid issue (https://github.com/grails/grails-core/issues/10196)
//provided "org.codehaus.groovy:groovy-ant"

The same setup was working in the Grails 3.2.0.

Any idea about this exception?


Solution

  • Seems to be an issue with Grails 3.2.1 itself. Issue tracked grails/grails-core#10244.

    Workaround is to override limitScanningToApplication in your grails-app/init/PACKAGE/Application.groovy

    import grails.boot.GrailsApp
    import grails.boot.config.GrailsAutoConfiguration
    
    class Application extends GrailsAutoConfiguration {
        static void main(String[] args) {
            GrailsApp.run(Application, args)
        }
    
        @Override
        boolean limitScanningToApplication() {
            return false
        }
    }