In my a previous project I was told to do authentication using spring-security where user can login with username or email and both can be case insensitive. For implementing the same I did following:
First install the spring-security-core plugin in your application and configure it. If you are new for spring-security-core plugin then go through this blog and After configuring pluging Create a Groovy class in your src/groovy directory which looks like :
class UserDetail 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 { User.withTransaction { status -> User user = User.findByUsernameIlikeOrEmailIlike(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) } }
Here we have provide our own implementation for loading the user. And after doing that you have to define this class in your conf/spring/resources.groovy like
beans = { userDetailsService(com.yourpackage.UserDetail) }
Here we are overriding the bean in spring. Now you are able to login with case insensitive username or email.
Hope this helps some one.
Hi Amit,
Thanks for this great solution. It just implemented it in our application!
Just one comment. You use ‘ilike’ to do a case-insensitive search for username or email address. This however allows for wildcard searches (e.g. wolfram.stacklies%), which I consider a potential security issue.
I recommend to use criteria instead:
User user = User.withCriteria(uniqueResult: true) {
or {
eq(“username”, username, [ignoreCase: true])
eq(“email”, username, [ignoreCase: true])
}
}
Also, the following includes (spring security 1.x) are required, maybe you add the to the class definiton?
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
Thanks for this greate post,
Wolfram