CodeGym /Cursos /Módulo 5. Spring /Conceptos básicos: autenticación y autorización

Conceptos básicos: autenticación y autorización

Módulo 5. Spring
Nivel 17 , Lección 1
Disponible

Para entender cómo funcionan los sistemas de seguridad, hay que distinguir claramente dos conceptos clave: autenticación y autorización. Ya empezamos a hablar de ellos, pero ahora vamos a aclarar las cosas para que no te confundas y lo recuerdes de una vez por todas.

Imagina que vas a casa de un amigo. Lo primero que haces es tocar el timbre. El amigo mira por la mirilla comprobando que eres tú y no algún tipo raro. Eso es autenticación — verificar que eres quien dices ser. Y luego el amigo decide: "Vale, te dejo pasar al salón, pero al dormitorio — ¡ni hablar!" Eso es — autorización.

En el contexto de aplicaciones y sistemas de seguridad:

  • Autenticación responde a la pregunta: "¿Quién eres realmente?" Verificamos la autenticidad del usuario: usuario, contraseña, a veces la huella dactilar, o incluso un baile con la pandereta.
  • Autorización — otro nivel: "Vale, sé quién eres, pero ¿qué puedes hacer en mi aplicación?" Aquí todo depende de los permisos y roles.

¿Cómo funciona la autenticación en Spring Security?

Spring Security ofrece un amplio conjunto de herramientas para implementar la autenticación. Hay dos aspectos clave: definir el método de autenticación y almacenar los datos de los usuarios. Vamos a verlo.

Tipos de autenticación

  1. Form-login — el método más básico. El usuario introduce nombre y contraseña en un formulario HTML, los datos se envían al servidor y se verifican. Si todo está bien — se concede el acceso.

    Ejemplo de configuración:

    
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .anyRequest().authenticated() // Todas las peticiones requieren autenticación
                    .and()
                .formLogin() // Activamos la autenticación por formulario
                    .loginPage("/login") // Indicación de la ruta a la página de login personalizada
                    .permitAll();
        }
    }
    
  2. Basic Authentication — autenticación sencilla con envío de usuario/contraseña en cada petición (mala opción para producción sin HTTPS).
  3. Token-based Authentication (por ejemplo, JWT) — en lugar de enviar usuario/contraseña en cada paso, usamos un token que confirma la autenticación.
  4. OAuth2/OpenID Connect — un esquema más complejo, del que hablaremos más adelante en el curso.

¿Dónde almacenar usuarios y contraseñas?

  • In-memory — conveniente para testing. Todo se guarda en memoria volátil, desaparece al reiniciar.

    Ejemplo:

    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER")
            .and()
            .withUser("admin").password("{noop}admin").roles("ADMIN");
    }
    
  • En la base de datos — la forma real para producción. Usamos UserDetailsService para proporcionar la información de los usuarios desde la base de datos.
  • LDAP/Active Directory — integración con sistemas corporativos.

¿Cómo funciona la autorización en Spring Security?

Hemos averiguado quién es nuestro usuario (autenticación), pero ahora la siguiente pregunta es: "¿Y qué puede hacer?"

Permisos basados en roles (Role-based Access Control, RBAC)

Spring Security usa la idea de roles para gestionar el acceso. Un usuario puede tener roles, por ejemplo, ROLE_USER o ROLE_ADMIN. En base a esos roles configuramos el acceso a diferentes partes de la aplicación.

Ejemplo:


@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN") // Solo role ADMIN
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // Roles USER y ADMIN
            .anyRequest().authenticated();
}

Autorización a nivel de métodos

A veces necesitas restringir acceso no por URL, sino a métodos concretos en tu código. Por ejemplo, solo un administrador puede eliminar usuarios.

Ejemplo con la anotación @PreAuthorize:


@Service
public class UserService {

    @PreAuthorize("hasRole('ADMIN')") // Solo el administrador puede
    public void deleteUser(String username) {
        // Lógica para eliminar al usuario
    }
}

Escenarios reales

Escenario 1: Solo los usuarios registrados pueden ver los perfiles

Queremos que la página de perfil esté disponible solo para usuarios autenticados. Esto se configura fácilmente:


http
    .authorizeRequests()
        .antMatchers("/profile/**").authenticated() // Solo autenticados
        .and()
    .formLogin();

Escenario 2: El administrador puede añadir nuevos datos, pero no modificarlos

En tu lógica de negocio los administradores pueden añadir registros, pero las modificaciones son prerrogativa de los managers. Usamos control a nivel de método:


@Service
public class DataService {

    @PreAuthorize("hasRole('ADMIN')")
    public void addData(Data data) {
        // Lógica para añadir datos
    }

    @PreAuthorize("hasRole('MANAGER')")
    public void updateData(Data data) {
        // Lógica para actualizar datos
    }
}

Errores comunes de principiantes

Uno de los errores más frecuentes al configurar autenticación/autorización es usar un orden incorrecto en las reglas. Por ejemplo, si pones anyRequest().permitAll() antes que las demás reglas, tu aplicación permitirá el acceso a todo el mundo.

Ejemplo de orden incorrecto:


http
    .authorizeRequests()
        .anyRequest().permitAll() // ¡Abre todo para todo el mundo!
        .antMatchers("/admin/**").hasRole("ADMIN");

Orden correcto:


http
    .authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .anyRequest().permitAll();

Así que presta atención al orden de las reglas.


¿Cómo se aplica esto en la vida real?

Construimos aplicaciones donde la seguridad es una parte esencial. Las habilidades para configurar roles y autenticación te servirán en cualquier sitio, desde una tienda online sencilla hasta sistemas complejos de gestión financiera. Por ejemplo, si desarrollas una aplicación para un banco, tendrás que considerar no solo los roles de los usuarios, sino también niveles de acceso, sistemas complejos de tokens y mucho más.

Spring Security es lo bastante flexible para afrontar cualquier tarea. Entender los fundamentos de autenticación y autorización es tu primer paso para desarrollar aplicaciones realmente seguras.


En la próxima clase veremos con más detalle las anotaciones de Spring Security, como @Secured, @PreAuthorize y otras, que te ayudarán a gestionar la seguridad a nivel de código.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION