3

Grails 2.0.3 では、Spring Security Core をインストールし、チュートリアルに従って User、UserRole、および Role オブジェクトを作成しました: http://blog.springsource.org/2010/08/11/simplified-spring-security-with-grails /

別のデータベースからオブジェクトにアクセスする準備として、2 番目のデータソースを追加することを決定するまで、すべてうまくいきました。DataSource.groovy は次のようになります。

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'
    }
}

datasource_product を追加しただけなのに、ログインできません。これをコメントアウトして (Bootstrap.groovy で) ユーザーを再作成すると、再度ログインできます。Bootstrap.groovy には以下が含まれます。

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 )
}

何か案は?

4

3 に答える 3

6

ガァァァァァ。これを見つけました: http://jira.grails.org/browse/GRAILS-8237 - どうやら、すべてのデータソースの各ドメインで beforeInsert が呼び出されます。これは、私の User オブジェクトで encodePassword が 2 回呼び出されていることを意味します - パスワードを二重にエンコードしています:

def beforeInsert() {
    encodePassword()
}

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

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

JIRA でパッチを見ましたが、リリースされるまでは、isPasswordEncoded フラグを使用して回避策を作成し、User での複数のエンコードを防止しました。

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

    def beforeUpdate() {
        if (isDirty('password')) {
            isPasswordEncoded = false
            encodePassword()
        }
    }
....snip....
}
于 2012-05-22T12:10:11.200 に答える
3

元の回答によって投稿されたコード ソリューションは、更新には機能しません。また、同じオブジェクト インスタンスへの複数の更新も考慮されません。挿入操作と更新操作には別々のフラグを使用し、それらを一時的としてマークして保持しないようにし、afterUpdate() イベント ハンドラーを使用してこれらのフラグをリセットします。

    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
    }
于 2013-01-10T11:51:45.600 に答える
0

同様の問題がありました。追記忘れてたから

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

その後、認証は機能していました。

于 2014-07-05T11:16:12.953 に答える