Grails 2 can't login with spring security when using multiple databases

China☆狼群 提交于 2020-01-23 10:43:26

问题


On Grails 2.0.3, I installed Spring Security Core and created the User, UserRole and Role objects as per the tutorial: http://blog.springsource.org/2010/08/11/simplified-spring-security-with-grails/

All went fine until I decided to add a second datasource in preparation for accessing objects from a different database. DataSource.groovy looks like this:

test {
    dataSource_product {
        dbCreate = "update"
        url = "jdbc:mysql://localhost/products"
        pooled = true
        driverClassName = "com.mysql.jdbc.Driver"
        username = "blah"
        password = "blah"
        loggingSql = true
        dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect'
    }
    dataSource {
        dbCreate = "update"
        url = "jdbc:mysql://localhost/core"
        pooled = true
        driverClassName = "com.mysql.jdbc.Driver"
        username = "blah"
        password = "blah"
        loggingSql = true
        dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect'
    }
}

Now I can't log in - even though all I have done is add datasource_product. If I comment this out and recreating the users (in Bootstrap.groovy) then I can log in again. Bootstrap.groovy contains:

def init =
{ servletContext ->

    // Add in roles
    Role.withTransaction { 
        def adminRole = Role.findByAuthority ( Role.ROLE_ADMIN ) ?: new Role ( authority: Role.ROLE_ADMIN ).save ( failOnError: true )

        def adminUser = User.findByUsername ( 'admin' ) ?: new User (
                username: 'blah',
                password: 'blah',
                enabled: true ).save ( failOnError: true )
        if ( !adminUser.authorities.contains ( adminRole ) ) UserRole.create ( adminUser, adminRole )
}

Any ideas?


回答1:


Gaaaahh. Found this: http://jira.grails.org/browse/GRAILS-8237 - apparently, beforeInsert gets called on each domain for every datasource. This means that, in my User object encodePassword is getting called twice - I'm double-encoding the password:

def beforeInsert() {
    encodePassword()
}

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

protected void encodePassword() {
    password = springSecurityService.encodePassword(password)
}

I saw a patch in the JIRA, but until it gets into the release, I created a workaround using an isPasswordEncoded flag to prevent multiple encodes in User:

class User {
    boolean isPasswordEncoded = false
....snip....
    def beforeInsert() {
        if ( !isPasswordEncoded )
        {
            isPasswordEncoded = true
            encodePassword ()
        }
    }

    def beforeUpdate() {
        if (isDirty('password')) {
            isPasswordEncoded = false
            encodePassword()
        }
    }
....snip....
}



回答2:


Code solution posted by original answer doesn't work for update. And also doesn't consider multiple updates to same object instance. I use separate flags for insert and update operations, mark them as transient so they're not persisted, and use the afterUpdate() event handler to reset these flags.

    static transients = ['beforeInsertRunOnce','beforeUpdateRunOnce']
    boolean beforeInsertRunOnce
    boolean beforeUpdateRunOnce

    def beforeInsert() {
        if (! beforeInsertRunOnce) {
            beforeInsertRunOnce = true
            encodePassword()
        }
    }

    def afterInsert() {
        beforeInsertRunOnce = false
    }

    def beforeUpdate() {
        if (isDirty('password') && ! beforeUpdateRunOnce ) {
            beforeUpdateRunOnce = true
            encodePassword()
        }
    }

    def afterUpdate() {
        beforeUpdateRunOnce = false
    }



回答3:


I did have similar issue. Was because I've forgotten to add

grails.plugin.springsecurity.userLookup.userDomainClassName ='yourpackage.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName =yourpackage.UserRole'
grails.plugin.springsecurity.authority.className ='yourpackage.Role'

After that authentication was working.



来源:https://stackoverflow.com/questions/10695592/grails-2-cant-login-with-spring-security-when-using-multiple-databases

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!