wureka
wureka

Reputation: 865

Grails Spring Security how to customize (or add) other authentication rules

I am using Grails 2.4.4 and Spring Security plugin RC4 to build my web site's authentication and authorization. The below is my User class:

class Member {
    transient springSecurityService
    long id
    String loginEmail
    String username
    String password
    String mobilePhone
    String nickName
    String lastName
    String firstName
    String validateCode
    String mobilePhoneNo
    boolean mobilePhoneIsValidated
    String mobilePhoneValidateCode
    Picture avatar
    Date lastSuccessfullyLoginTime
    Date lastTryingLoginTime
    int loginFailedCount
    Date dateCreated
    Date lastUpdated
    String createdBy
    String updatedBy
    String validateStatus
    boolean enabled = false
    boolean accountExpired = false
    boolean accountLocked = true
    boolean passwordExpired = true

    static transients = ['springSecurityService']

    static hasMany = [insiderInfos:InsiderInfo, memberEvaluateNews:MemberEvaluateNews, loginHistories:LoginHistory]

    static constraints = {
        username                    blank: false, unique: true
        password                    blank: false
        loginEmail                  email: true, blank: false, unique: true
        mobilePhone                 blank: false
        lastName                    blank: false
        firstName                   blank: false
        mobilePhoneNo               nullable: true
        nickName                    nullable:true
        avatar                      nullable: true
        mobilePhoneIsValidated      nullable:false
        mobilePhoneValidateCode     nullable: true;
        lastSuccessfullyLoginTime   nullable:true
        lastTryingLoginTime         nullable: true
        validateStatus              blank: false //, inList: ValidateStatusEnum.values()*.id
        createdBy                   shared:'varchar20'
        updatedBy                   shared:'varchar20'
    }

    static mapping = {
        comment('會員主檔')
        id                          generator: 'identity'
        loginFailedCount            comment:'登入錯誤的次數',   defaultValue:0
        password                    comment:'密碼',length: 64
        mobilePhone                 comment:'行動電話號碼', length: 20
        accountLocked               comment:'帳號是否被鎖住'
        passwordExpired             comment:'帳號是否過期/停用'
        validateStatus              comment:"驗證狀態,WAIT_VALIDATE,VALIDATE_FAILED,SUCCESS",length: 20
        validateCode                comment:'驗證碼', length: 64
        lastTryingLoginTime         comment:'上次嘗試登入的時間'
        lastSuccessfullyLoginTime   comment:'上次成功登入的時間'
        insiderInfos                comment:'會員提供的內線消息'
        mobilePhoneIsValidated      comment:'行動電話號碼是否通過驗證', defaultValue:false
        mobilePhoneValidateCode     comment:'行動電話驗證碼',length:10
        mobilePhoneNo               comment:'行動電話號碼', length: 20
        username                    comment:'user name', length: 20
        nickName                    comment:'假名', length:20
        lastName                    comment:'姓氏', length: 10
        firstName                   comment:'名字', length: 20
        avatar                      comment:'大頭照編號(在 Picture 裡的號碼)'
        createdBy                   length: 20
        updatedBy                   length: 20
        //password column: '`password`',comment:'密碼',length: 64
    }


    Set<Role> getAuthorities() {
        MemberRole.findAllByMember(this).collect { it.role }
    }

    def beforeInsert() {
        encodePassword()
    }

    def beforeUpdate() {
        if (isDirty('password')) {
            encodePassword()
        }
    }
    String fullName () {
        return "${lastName + firstName}"
    }

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

    ValidateStatusEnum getValidateStatus() {
        return validateStatus? ValidateStatusEnum.byId(validateStatus): null
    }

    void setValidateStatus(ValidateStatusEnum localValidateStatusEnum) {
        validateStatus = localValidateStatusEnum.id
    }
}

Besides the Spring Security's built-in authentication rule, I need one more authentication rule, which is:

  1. A member can login with either username or loginEmail

How do I add the above rule ?

Upvotes: 1

Views: 95

Answers (1)

injecteer
injecteer

Reputation: 20707

you have to go for a custom UserDetailService, as described in the spring-core docs:

class UsernameOrEmailUserDetailsService implements GrailsUserDetailsService {

  UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User.withTransaction { status ->
       User user = User.findByUsernameOrLoginEmail(username, username)
       return new GrailsUser( user.username, user.password, ..., user.id )
      } 
    }
  }
}

Upvotes: 0

Related Questions