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

springSecurityService is not injected into domain classes #372

Closed
damluar opened this issue Aug 25, 2015 · 14 comments
Closed

springSecurityService is not injected into domain classes #372

damluar opened this issue Aug 25, 2015 · 14 comments

Comments

@damluar
Copy link

damluar commented Aug 25, 2015

I followed the spring security plugin tutorial for my existing project and created domain classes for user and role as described in tutorial.
But when the encodePassword() method is called, the springSecurityService is null

protected void encodePassword() {
    password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}

I looked at the grails output, but everything looks fine:

WARN grails.plugin.springsecurity.SpringSecurityCoreGrailsPlugin - 
Configuring Spring Security Core ...

Configuring Spring Security Core ...
WARN grails.plugin.springsecurity.SpringSecurityCoreGrailsPlugin - ... finished configuring Spring     Security Core

... finished configuring Spring Security Core

Out of curiosity I created a new empty grails project and as expected springSecurityService is injected correctly.
Is there any security plugin log or how could I understand why the service is null?

@burtbeckwith
Copy link
Contributor

Did you remove the call to this() in the parameterized constructor?

@damluar
Copy link
Author

damluar commented Aug 25, 2015

Yes, I did. Intellij was complaining about "Recursive constructor invocation". Could you explain the purpose of this() please? Thank you very much!

@damluar damluar closed this as completed Aug 25, 2015
@bdbogjoe
Copy link

Can you explain more what was the issue ?

@damluar
Copy link
Author

damluar commented Aug 26, 2015

I used a script grails s2-quickstart com.testapp User Role to generate those domain classes, but Intellij highlights constructor call as red ("Recursive constructor invocation"):

User(String username, String password) {
    this()
    this.username = username
    this.password = password
}

And I decided to remove the call to this() to fix it. This broke the injection of transient springSecurityService property somehow, so there is some logic in this()

@burtbeckwith
Copy link
Contributor

I discussed this in my "Little Did He Know" talk at Greach and GR8Conf. Here's a link for the talk at Greach: https://www.youtube.com/watch?v=Oxwpqh1h0s0 - It's one of the first topics so you don't need to watch the whole thing (but feel free to do so ;)

I created an issue in the IDEA bug tracker so hopefully they'll have a fix in an upcoming release. For now it's frustrating to have a false error in the IDE, but it's safe to ignore since everything works at runtime.

@bdbogjoe
Copy link

ok thanks for info

@damluar
Copy link
Author

damluar commented Aug 26, 2015

Thank you Burt! Could have a look at http://stackoverflow.com/questions/32222792/angular-frontend-authentication-when-using-grails-and-spring-security-for-backen please? I'm having a hard time to do the authentication right...

@alex-shamshurin
Copy link

BTW, how to supress error warning (recurisive constructor on this() )in IDEA? Turning off inspections does not help

@burtbeckwith
Copy link
Contributor

The issue I raised in their bug tracker is scheduled for the version 15 release: https://youtrack.jetbrains.com/issue/IDEA-144371

@vitorbertazoli
Copy link

@burtbeckwith I've been trying to use springSecurityService on the domain class but it seems it's always null. I created a project and added spring-security-rest as dependency. Then I ran s2-quickstart to generate the User and Role classes. If I open the grails console and instantiate a new User() springSecurityService will be null.
I've uploaded the example here:
https://github.com/vitorbertazoli/GrailsTest

@burtbeckwith
Copy link
Contributor

Having parameterized constructors works well in 3.0.x when people understand what's going on and don't comment out that call to this() but wasn't reliable in 3.1.x so I changed the template to not use them. Does it work for you if you remove the constructor and create instances with the Map constructor like other domain classes (e.g. new User(username: ..., password: ...)?

@vitorbertazoli
Copy link

@burtbeckwith it didn't work with the Map constructor either.

@burtbeckwith
Copy link
Contributor

Did you remove or comment out the parameterized constructor? Using the map constructor isn't a workaround - having the parameterized constructor causes dependency injection to fail all or part of the time, so it has to be removed.

@vitorbertazoli
Copy link

vitorbertazoli commented Jul 26, 2016

@burtbeckwith I removed the constructor, it didn't work. This is what the class looks like:

package little

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {

        private static final long serialVersionUID = 1

        transient springSecurityService

        String username
        String password
        boolean enabled = true
        boolean accountExpired
        boolean accountLocked
        boolean passwordExpired

        Set<Role> getAuthorities() {
                UserRole.findAllByUser(this)*.role
        }

        def beforeInsert() {
                encodePassword()
        }

        def beforeUpdate() {
                if (isDirty('password')) {
                        encodePassword()
                }
        }

        protected void encodePassword() {
                password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
        }

        static transients = ['springSecurityService']

        static constraints = {
                username blank: false, unique: true
                password blank: false
        }

        static mapping = {
                password column: '`password`'
        }
}

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

5 participants