Secciones

Utilizar correo electrónico con Spring Security Core

Inicio » Artículos » Utilizar correo electrónico con Spring Security Core
La categoría del artículo es
Escrito el 12 August 2012, 16:35


Actualmente estoy trabajando en un proyecto del que en breve esperamos tener una primera release y del que todavía no puedo comentar nada. En este proyecto, he tenido que realizar una serie de modificaciones a un plugin que siempre utilizo en cualquier proyecto de Grails que requiera de autenticación mediante usuario y contraseña. Este plugin es Spring Security Core.

Este plugin permite fácilmente implementar todo un sistema de seguridad en una aplicación desarrollada en Grails mediante nombre de usuario y contraseña. En este proyecto necesitaba ampliar este plugin para que en además de poder identificarse mediante nombre de usuario también se pudiera hacer mediante el correo electrónico.

Para poder implementar estos cambios, lo primero que debemos hacer es ampliar la clase relativa a los usuarios del plugin Spring Security Core. Habitualmente esta clase se llama User y quedaría algo así:

Groovy:
class User {

        transient springSecurityService

        String username
        String password
        boolean enabled
        boolean accountExpired
        boolean accountLocked
        boolean passwordExpired
    String email


        static constraints = {
                username blank: false, unique: true
        password blank: false
        email blank:false, unique:true, email:true
        }
       
        ....
}

Posteriormente, debemos crear una clase en el directorio src/groovy para extender la clase GrailsUser que a su vez extiende a la clase User.

Groovy:
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser

import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.User

class MyUserDetails extends GrailsUser {

    final String email
    final String name
    final String surnames

    MyUserDetails(String username,
                  String password,
                  boolean enabled,
                  boolean accountNonExpired,
                  boolean credentialsNonExpired,
                  boolean accountNonLocked,
                  Collection<GrantedAuthority> authorities,
                  long id,
                  String email) {
        super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id)

        this.email = email
    }
}

Por último, debemos crear un servicio de Grails donde modificaremos el comportamiento de la autenticación en Grails para que en lugar de comprobar únicamente por el nombre de usuario, lo haga también con el email que acabamos de añadir.

Groovy:
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
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

class MyUserDetailsService implements GrailsUserDetailsService {

/** * Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least * one role, so we give a user with no granted roles this one which gets * past that restriction but doesn't grant anything. */
    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 MyUserDetails(user.username,
                    user.password,
                    user.enabled,
                    !user.accountExpired,
                    !user.passwordExpired,
                    !user.accountLocked,
                    authorities ?: NO_ROLES,
                    user.id,
                    user.email)
        }
    }
}

Con estos cambios, ya podremos identificar a los usuarios de nuestra aplicación tanto con el nombre de usuario como por el correo electrónico. Incluso vamos a poder utilizar la etiqueta loggedInUserInfo para mostrar el correo electrónico del usuario identificado en el sistema.

Groovy:
<sec:loggedInUserInfo field="email"/>

Podéis encontrar más información al respecto en la documentación del plugin Spring Security Core y en el blog de Omar Marji.


Espero tus comentarios...

Ayuda Textile