authentication - grails spring security acl query exception -
i trying authenticate user email address using spring security acl. want use email address of accountperson belongs user domain object. when save user works fine , database updates correctly when try authenticate hibernate.queryexception: not resolve property: accountperson.email of: com.loggyt.user
here code , error messages. appreciated. thanks
accountperson.groovy
class accountperson implements serializable{ string firstname string lastname address address string email string primaryphone string secondaryphone static belongsto = [user:user] static mapping = { address cascade: 'all' } date datecreated date lastupdated static constraints = { firstname nullable: false, blank: false lastname nullable: false, blank: false address nullable: true primaryphone blank: false, nullable: false secondaryphone blank: true, nullable: true email nullable: false, blank: false, email: true, unique: true } }
user.groovy:
import java.util.date class user implements serializable{ transient springsecurityservice transient string password boolean enabled boolean accountexpired boolean accountlocked boolean passwordexpired date datecreated date lastupdated static hasone = [accountperson: accountperson] static constraints = { password blank: false accountperson bindable: true password bindable: true } static mapping = { password column: '`password`' accountperson fetch: 'join' } set<role> getauthorities() { userrole.findallbyuser(this).collect { it.role } set } void beforeinsert() { encodepassword() } void beforeupdate() { if (isdirty('password')) { encodepassword() } } /** * after user has been updated database, log user in * using new credentials. */ void afterupdate() { this.discard() this.springsecurityservice.reauthenticate(person.email) } /** * user based on email address. * * @param email email of user * @return user has email parameter */ static user findbyemail(string email){ user.createcriteria().get{ accountperson{ eq('email', email) } } } protected void encodepassword() { password = this.springsecurityservice.encodepassword(password) } }
config
// added spring security core plugin: grails.plugins.springsecurity.userlookup.userdomainclassname = 'com.loggyt.user' grails.plugins.springsecurity.userlookup.usernamepropertyname = 'accountperson.email' grails.plugins.springsecurity.userlookup.passwordpropertyname = 'password' grails.plugins.springsecurity.userlookup.authorityjoinclassname = 'com.loggyt.userrole' grails.plugins.springsecurity.authority.classname = 'com.loggyt.role'
bootstrap
def dbcreate = grailsapplication.config.datasource.dbcreate if(dbcreate == "create" || dbcreate == "create-drop"){ /** * create roles. * */ def adminrole = new role(authority: 'role_admin').save(flush:true) def userrole = new role(authority: 'role_user').save(flush:true) def person = new accountperson( firstname: 'otto', lastname: 'admin', email: "noreply@loggyt.com", primaryphone: "555-555-5555") def user = new user (enabled: true, password: "password") user.accountperson = person user.save(flush:true) userrole.create user, adminrole, true person = new accountperson( firstname: 'normal', lastname: 'user', email: "user@loggyt.com", primaryphone: "555-555-5555") user = new user (enabled: true, password: "password") user.accountperson = person user.save(flush:true) userrole.create user, userrole, true assert user.count() == 2 assert role.count() == 2 assert userrole.count() == 2 } }
log4j debug message
2013-07-07 00:57:33,088 [http-bio-8443-exec-3] debug authentication.providermanager - authentication attempt using org.springframework.security.authentication.dao.daoauthenticationprovider 2013-07-07 00:57:33,138 [http-bio-8443-exec-3] debug datasource.datasourceutils - fetching jdbc connection datasource 2013-07-07 00:57:33,162 [http-bio-8443-exec-3] debug support.transactiontemplate - initiating transaction rollback on application exception message: not resolve property: accountperson.email of: com.loggyt.user; nested exception org.hibernate.queryexception: not resolve property: accountperson.email of: com.loggyt.user line | method ->> 592 | findwhere in org.grails.datastore.gorm.gormstaticapi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 686 | withtransaction in '' | 1110 | runworker . . . in java.util.concurrent.threadpoolexecutor | 603 | run in java.util.concurrent.threadpoolexecutor$worker ^ 722 | run . . . . . . in java.lang.thread caused queryexception: not resolve property: accountperson.email of: com.loggyt.user ->> 592 | findwhere in org.grails.datastore.gorm.gormstaticapi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 686 | withtransaction in '' | 1110 | runworker . . . in java.util.concurrent.threadpoolexecutor | 603 | run in java.util.concurrent.threadpoolexecutor$worker ^ 722 | run . . . . . . in java.lang.thread
i believe default userdetailsservice looks user based on username, in addition you've configured, you'll need create custom userdetailsservice , implement loaduserbyusername method. here's quick example:
class customuserdetailsservice implements grailsuserdetailsservice { userdetails loaduserbyusername(string username, boolean loadroles) throws usernamenotfoundexception { return loaduserbyusername(username) } userdetails loaduserbyusername(string username) throws usernamenotfoundexception { user.withtransaction { status -> user user = user.findbyemail(username) if (!user) { throw new usernamenotfoundexception('user not found', username) } def authorities = user.authorities.collect { new grantedauthorityimpl(it.authority) } return new grailsuser(user.username, user.password, user.enabled, !user.accountexpired, !user.passwordexpired, !user.accountlocked, authorities ?: no_roles, user.id ) } } }
then notify grails of new userdetailsservice implementation in conf/spring/resources.groovy
beans = { userdetailsservice(com.loggyt.customuserdetailsservice) }
Comments
Post a Comment