Patrick Hütter

Grails: User Authentifizierung / Login via E-Mail und Username mit Spring Security Core

Wer Spring-Security-Core in seiner Grails WebApp für die Authentifizierung und den Login nutzt weiß, dass man sich in der standardmäßigen Variante nur via Username einloggen kann. Wer für seine WebApp aber lieber eine E-Mail Authentifizierung oder beides (E-Mail und Username) haben möchte, dem sei folgendes ans Herz gelegt.

1. E-Mail Attribut dem Usermodel (Domain Model) hinzufügen. Das kann bei euch der die normale User.groovy Klasse sein, oder auch die entsprechenden Usermodels, die von User erben.

String email

Zusätzlich kann man einen Constraint für E-Mail Validation (ist im Grails Framework enthalten) anlegen (User.groovy):

email blank: false, email: true

2. GrailsUserDetailsService Interface implementieren: CustomUserDetailsService.groovy
Im services Ordner implementiert man nun GrailsUserDetailsService und ändert den dynamic finder in der loadByUsername(String username) Methode zu User.findByUsernameOrEmail(username, username) ab.


package com.encircle360.secretProject.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
import com.encircle360.secretProject.security.User

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 {

User.withTransaction { status ->
 User user = User.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)
 }
 }
}

Zuletzt trägt man in die conf/spring/resources.groovy die eben erstelle Bean ein.

// Place your Spring DSL code here
beans = {
	userDetailsService(com.encircle360.secretProject.customAuth.CustomUserDetailsService)
}

Jetzt die App starten oder neustarten und mit der E-Mail Adresse oder dem Username einloggen! Viel Spaß damit! 🙂

Die mobile Version verlassen