1. Implement the first requirement – Add an email address property to the user domain
This is really simple, just add the property to the domain class
2. Implement the second requirement – Authenticate using the username or the email
In order to implement this requirement, I will have to implement a new UserDetailsService
3. With the custom service in place, I need to register it in grails-app/conf/spring/resources.groovy by adding
This is really simple, just add the property to the domain class

- package org.customauth
- class CustomUser {
- String username
- String password
- String email
- boolean enabled
- boolean accountExpired
- // *******
- // the rest of the generated class contents
- // *******
- }
2. Implement the second requirement – Authenticate using the username or the email
In order to implement this requirement, I will have to implement a new UserDetailsService
- package org.customauth
- import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser
- import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService
- import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
- import org.springframework.security.core.authority.GrantedAuthorityImpl
- import org.springframework.security.core.userdetails.UserDetails
- import org.springframework.security.core.userdetails.UsernameNotFoundException
- class CustomUserDetailsService implements GrailsUserDetailsService {
- static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
- UserDetails loadUserByUsername(String username, boolean loadRoles)
- throws UsernameNotFoundException {
- return loadUserByUsername(username)
- }
- UserDetails loadUserByUsername(String username)
- throws UsernameNotFoundException {
- CustomUser.withTransaction { status ->
- CustomUser user = CustomUser.findByUsernameOrEmail(username, 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)
- }
- }
- }
3. With the custom service in place, I need to register it in grails-app/conf/spring/resources.groovy by adding
- beans = {
- userDetailsService(org.customauth.CustomUserDetailsService)
- }