Spring Boot

SpringBoot

Tutorial SpringBoot: Autenticación y autorización con anotaciones

Aprende a aplicar seguridad a nivel de método con las anotaciones de Spring Security: @Secured, @RolesAllowed, @PermitAll @PreAuthorize, @PostAuthorize y @PreFilter y @PostFilter y SpEL.

Aprende SpringBoot GRATIS y certifícate

Seguridad con @Secured, @RolesAllowed, @PermitAll

En Spring Security, la protección de métodos mediante anotaciones es una forma eficaz de controlar el acceso a recursos específicos en una aplicación. Las anotaciones @Secured, @RolesAllowed y @PermitAll permiten definir reglas de seguridad directamente sobre los métodos de nuestros controladores y servicios, facilitando la implementación de autorización basada en roles y permisos.

Configuración previa

Antes de utilizar estas anotaciones, es fundamental habilitar la seguridad a nivel de método en nuestra aplicación. Para ello, es necesario agregar la anotación @EnableMethodSecurity en una clase de configuración o en la clase principal de la aplicación:

@Configuration
@EnableMethodSecurity
public class SecurityConfig {
    // Configuración de seguridad
}

Esta anotación activa la seguridad basada en anotaciones para métodos, permitiendo que Spring Security interpole los aspectos necesarios para el control de acceso.

Uso de @Secured

La anotación @Secured permite especificar los roles que un usuario debe tener para acceder a un método específico. Los roles se definen como cadenas de texto y, por convención, suelen comenzar con el prefijo "ROLE_". Por ejemplo:

@Secured("ROLE_ADMIN")
public void crearUsuario(Usuario usuario) {
    // Lógica para crear un usuario
}

En este caso, solo los usuarios con el rol ADMIN podrán ejecutar el método crearUsuario. Es posible especificar múltiples roles utilizando un array:

@Secured({"ROLE_ADMIN", "ROLE_GESTOR"})
public void eliminarUsuario(Long id) {
    // Lógica para eliminar un usuario
}

Aquí, el método eliminarUsuario será accesible para usuarios con los roles ADMIN o GESTOR.

Uso de @RolesAllowed

La anotación @RolesAllowed es similar a @Secured, pero forma parte de la especificación JSR-250. Para utilizarla, es necesario incluir la dependencia correspondiente en el proyecto. Esta anotación también permite especificar roles requeridos para acceder a un método:

@RolesAllowed("ROLE_USUARIO")
public void verPerfil() {
    // Lógica para ver el perfil del usuario
}

Al igual que con @Secured, es posible indicar múltiples roles:

@RolesAllowed({"ROLE_USUARIO", "ROLE_ADMIN"})
public void actualizarPerfil(Usuario usuario) {
    // Lógica para actualizar el perfil
}

Diferencias entre @Secured y @RolesAllowed

Aunque ambas anotaciones se utilizan para controlar el acceso basado en roles, existen algunas diferencias clave:

Especificación: @Secured es específica de Spring Security, mientras que @RolesAllowed proviene de la especificación estándar JSR-250.

Configuración: Para usar @RolesAllowed, es necesario incluir la dependencia jakarta.annotation:jakarta.annotation-api y asegurarse de que esté correctamente configurada.

Uso de @PermitAll

La anotación @PermitAll permite que un método sea accesible por cualquier usuario, autenticado o no. Es útil cuando se ha aplicado una política de seguridad restrictiva por defecto y se desea abrir el acceso a métodos específicos:

@PermitAll
public void verProductos() {
    // Lógica para mostrar productos disponibles
}

Con @PermitAll, no es necesario que el usuario tenga un rol específico ni que esté autenticado para acceder al método verProductos.

Consideraciones de seguridad

Prioridad de anotaciones: Si se configuran reglas de seguridad tanto a nivel de clase como de método, las anotaciones a nivel de método tienen prioridad.

Prefijo de roles: Es importante mantener la coherencia en el uso del prefijo "ROLE_" para los roles. Esto garantiza que la resolución de roles funcione correctamente en Spring Security.

Combinación con otras anotaciones: Las anotaciones @Secured, @RolesAllowed y @PermitAll pueden coexistir en la misma aplicación, pero se debe ser cuidadoso para evitar conflictos en las reglas de acceso.

Ejemplo práctico

Supongamos que tenemos un servicio de gestión de pedidos y queremos controlar el acceso a sus métodos:

@Service
public class PedidoService {

    @Secured("ROLE_ADMIN")
    public void procesarPedido(Long id) {
        // Lógica para procesar un pedido
    }

    @RolesAllowed("ROLE_CLIENTE")
    public Pedido verPedido(Long id) {
        // Lógica para ver detalles de un pedido
        return pedido;
    }

    @PermitAll
    public List<Producto> listarProductos() {
        // Lógica para listar productos disponibles
        return productos;
    }
}

En este ejemplo:

  • Solo los usuarios con rol ADMIN pueden procesar pedidos.
  • Los usuarios con rol CLIENTE pueden ver los detalles de sus pedidos.
  • Cualquier usuario, incluso sin autenticar, puede listar los productos disponibles.

Integración con controladores

Estas anotaciones también pueden aplicarse directamente en los controladores REST o MVC:

@RestController
@RequestMapping("/api/pedidos")
public class PedidoController {

    @Autowired
    private PedidoService pedidoService;

    @PostMapping("/procesar/{id}")
    @Secured("ROLE_ADMIN")
    public ResponseEntity<Void> procesar(@PathVariable Long id) {
        pedidoService.procesarPedido(id);
        return ResponseEntity.ok().build();
    }

    @GetMapping("/ver/{id}")
    @RolesAllowed("ROLE_CLIENTE")
    public ResponseEntity<Pedido> ver(@PathVariable Long id) {
        Pedido pedido = pedidoService.verPedido(id);
        return ResponseEntity.ok(pedido);
    }

    @GetMapping("/productos")
    @PermitAll
    public ResponseEntity<List<Producto>> productos() {
        List<Producto> productos = pedidoService.listarProductos();
        return ResponseEntity.ok(productos);
    }
}

De esta forma, se garantiza que el acceso a los endpoints de la API esté protegido según los roles de los usuarios.

Configuración de roles y usuarios

Para que las anotaciones funcionen correctamente, es imprescindible definir los usuarios y roles en el sistema de autenticación. Por ejemplo, si utilizamos una configuración en memoria:

@Bean
public InMemoryUserDetailsManager userDetailsService() {
    UserDetails admin = User.withUsername("admin")
        .password(passwordEncoder().encode("adminpass"))
        .roles("ADMIN")
        .build();
    UserDetails cliente = User.withUsername("cliente")
        .password(passwordEncoder().encode("clientepass"))
        .roles("CLIENTE")
        .build();
    return new InMemoryUserDetailsManager(admin, cliente);
}

Aquí, hemos creado dos usuarios:

  • admin con rol ADMIN.
  • cliente con rol CLIENTE.

Autenticación y autorización

Al iniciar la aplicación y acceder a los métodos protegidos, Spring Security se encargará de:

  • Autenticar al usuario mediante las credenciales proporcionadas.
  • Verificar si el usuario tiene los roles necesarios para ejecutar el método.
  • Denegar el acceso si no se cumplen las condiciones, retornando una respuesta adecuada, como 403 Forbidden.

El uso de @Secured, @RolesAllowed y @PermitAll proporciona una forma clara y declarativa de controlar el acceso a los métodos de nuestra aplicación. Al definir las reglas de seguridad directamente en el código, logramos una mayor coherencia y mantenibilidad en la gestión de permisos y roles.

Seguridad con @PreAuthorize, @PostAuthorize y @PreFilter y @PostFilter

En Spring Security, las anotaciones @PreAuthorize, @PostAuthorize, @PreFilter y @PostFilter ofrecen una manera avanzada de controlar el acceso a los métodos y de filtrar datos de entrada y salida. Estas anotaciones permiten definir reglas de autorización utilizando expresiones SpEL (Spring Expression Language), lo que proporciona una gran flexibilidad en la implementación de políticas de seguridad.

La anotación @PreAuthorize se emplea para evaluar una expresión antes de la ejecución de un método. Si la expresión resulta en false, el acceso se deniega y se lanza una excepción de seguridad. Por ejemplo:

@PreAuthorize("hasRole('ADMIN')")
public void eliminarUsuario(Long id) {
    // Lógica para eliminar un usuario
}

En este caso, solo los usuarios con el rol ADMIN podrán invocar el método eliminarUsuario. Esta anotación es útil para proteger métodos basados en los roles o permisos del usuario autenticado.

Por su parte, @PostAuthorize evalúa la expresión después de la ejecución del método. Esto permite tomar decisiones de autorización basadas en el resultado devuelto. Un ejemplo práctico es:

@PostAuthorize("returnObject.propietario == authentication.name")
public Documento obtenerDocumento(Long id) {
    // Lógica para obtener el documento
    return documento;
}

Aquí, el acceso al documento solo se permite si el propietario coincide con el nombre del usuario autenticado. La expresión verifica la propiedad propietario del objeto retornado contra el nombre de usuario actual.

Las anotaciones @PreFilter y @PostFilter se utilizan para filtrar colecciones o arrays antes o después de la ejecución del método. Esto es especialmente útil cuando se manejan listas de elementos y se desea aplicar criterios de seguridad sobre los mismos.

Un ejemplo de @PreFilter es:

@PreFilter("filterObject.visibilidad == 'PUBLICA'")
public void procesarDatos(List<Dato> datos) {
    // Lógica para procesar datos
}

En este caso, antes de ejecutar procesarDatos, la lista datos se filtra para incluir solo aquellos elementos cuya propiedad visibilidad sea 'PUBLICA'.

De manera similar, @PostFilter se puede aplicar para filtrar los resultados devueltos por un método:

@PostFilter("filterObject.autor == authentication.name")
public List<Articulo> listarArticulos() {
    // Lógica para listar artículos
    return articulos;
}

Aquí, después de ejecutar listarArticulos, la lista resultante se filtra para mostrar únicamente los artículos cuyo autor sea el usuario autenticado.

Es fundamental habilitar la seguridad a nivel de método para utilizar estas anotaciones. Esto se logra agregando @EnableMethodSecurity en una clase de configuración:

@Configuration
@EnableMethodSecurity
public class SeguridadConfig {
    // Configuración adicional
}

Las expresiones SpEL permiten acceder a detalles del contexto de seguridad, como el usuario autenticado, sus roles y autoridades. Por ejemplo:

@PreAuthorize("hasAuthority('PERMISO_EDITAR')")
public void editarPerfil(Perfil perfil) {
    // Lógica para editar el perfil
}

Este método solo es accesible para usuarios que tengan la autoridad PERMISO_EDITAR.

También es posible utilizar variables y parámetros en las expresiones:

@PreAuthorize("#id == principal.id or hasRole('ADMIN')")
public Perfil verPerfil(Long id) {
    // Lógica para ver el perfil
    return perfilService.obtenerPorId(id);
}

Aquí, el método verPerfil permite que un usuario vea su propio perfil o que un administrador vea el de cualquier usuario.

Cuando se trabaja con colecciones, @PreFilter y @PostFilter facilitan la aplicación de reglas de autorización sobre cada elemento. Por ejemplo:

@PreFilter("filterObject.tipo != 'RESTRINGIDO'")
public void enviarMensajes(List<Mensaje> mensajes) {
    // Lógica para enviar mensajes
}

Antes de ejecutar enviarMensajes, la lista mensajes se filtra para excluir aquellos de tipo 'RESTRINGIDO'.

Para métodos que devuelven colecciones, @PostFilter ayuda a presentar al usuario solo los datos que puede ver:

@PostFilter("filterObject.nivelAcceso <= principal.nivel")
public List<Documento> obtenerDocumentos() {
    // Lógica para obtener documentos
    return documentos;
}

Después de ejecutar obtenerDocumentos, se filtran los documentos cuyo nivelAcceso sea menor o igual al nivel del usuario autenticado.

Es importante tener en cuenta que el uso de estas anotaciones puede afectar el rendimiento si se aplican sobre colecciones grandes. Por ello, es recomendable diseñar las consultas y métodos para minimizar el impacto en la eficiencia.

Al implementar @PreAuthorize, @PostAuthorize, @PreFilter y @PostFilter, se consigue una seguridad más detallada y adaptable a diferentes escenarios. Estas anotaciones permiten centralizar la lógica de autorización en el código, facilitando su mantenimiento y comprensión.

Además, estas herramientas se integran perfectamente con otras características de Spring Security, como la gestión de roles y permisos, proporcionando un marco robusto para proteger aplicaciones empresariales.

Es esencial que los desarrolladores estén familiarizados con las expresiones SpEL y comprendan cómo acceder a las propiedades y métodos relevantes en el contexto de seguridad. Esto garantiza que las reglas de autorización sean precisas y efectivas.

El uso de @PreAuthorize, @PostAuthorize, @PreFilter y @PostFilter en Spring Security permite implementar controles de acceso avanzados y filtrar datos de manera flexible, aprovechando el poder de las expresiones SpEL y ofreciendo una capa adicional de seguridad en las aplicaciones.

Seguridad con expresiones SpEL en controladores

Las expresiones SpEL (Spring Expression Language) permiten definir reglas de seguridad avanzadas directamente en los controladores, proporcionando un control detallado sobre el acceso a los recursos. Al utilizar @PreAuthorize y @PostAuthorize en los métodos de los controladores, es posible evaluar condiciones basadas en los parámetros de entrada, el usuario autenticado y otros elementos del contexto.

Por ejemplo, se puede restringir el acceso a un método en función de un parámetro de ruta. Consideremos un controlador que permite a los usuarios obtener detalles de su propio perfil:

@GetMapping("/usuarios/{id}")
@PreAuthorize("#id == principal.id or hasRole('ADMIN')")
public ResponseEntity<Usuario> obtenerUsuario(@PathVariable Long id) {
    Usuario usuario = usuarioService.buscarPorId(id);
    return ResponseEntity.ok(usuario);
}

En este caso, la expresión SpEL #id == principal.id or hasRole('ADMIN') verifica si el ID proporcionado en la ruta coincide con el ID del usuario autenticado o si el usuario tiene el rol ADMIN. De esta forma, un usuario puede acceder a sus propios datos, mientras que los administradores pueden acceder a los datos de cualquier usuario.

Es posible acceder a los parámetros del método utilizando el símbolo # seguido del nombre del parámetro. Además, el objeto principal representa al usuario autenticado. Esto permite construir condiciones dinámicas basadas en los valores proporcionados en las peticiones.

Otro ejemplo común es restringir operaciones de modificación solo al propietario de un recurso. Supongamos un método para actualizar un artículo:

@PutMapping("/articulos/{id}")
@PreAuthorize("@articuloService.esPropietario(#id, principal.username)")
public ResponseEntity<?> actualizarArticulo(@PathVariable Long id, @RequestBody Articulo datosActualizados) {
    articuloService.actualizar(id, datosActualizados);
    return ResponseEntity.ok().build();
}

Aquí, la expresión SpEL utiliza un método del articuloService para verificar si el usuario autenticado es el propietario del artículo. Al utilizar @ seguido del nombre del bean, es posible invocar métodos de otros componentes dentro de la expresión.

Las expresiones SpEL también permiten acceder a variables especiales del contexto de seguridad. Por ejemplo, authentication proporciona acceso al objeto Authentication, permitiendo verificar detalles como las autoridades y los detalles del usuario:

@GetMapping("/documentos/{id}")
@PreAuthorize("authentication.principal.empresa == @documentoService.obtenerEmpresa(#id)")
public ResponseEntity<Documento> verDocumento(@PathVariable Long id) {
    Documento documento = documentoService.buscarPorId(id);
    return ResponseEntity.ok(documento);
}

En este caso, se comprueba que la empresa asociada al usuario autenticado coincide con la empresa del documento solicitado. Esto es útil en escenarios donde el acceso debe limitarse a cierta entidad o organización.

Para condiciones más complejas, es posible utilizar las operaciones lógicas disponibles en SpEL, como and, or y not. Por ejemplo:

@PostMapping("/comentarios")
@PreAuthorize("hasRole('USUARIO') and #comentario.texto.length() <= 500")
public ResponseEntity<?> crearComentario(@RequestBody Comentario comentario) {
    comentarioService.crear(comentario);
    return ResponseEntity.status(HttpStatus.CREATED).build();
}

Esta expresión asegura que solo los usuarios con el rol USUARIO puedan crear comentarios y que el texto del comentario no exceda los 500 caracteres.

Además de los parámetros del método y el usuario autenticado, también es posible acceder a los headers y otros elementos de la petición. Sin embargo, esto requiere exponerlos como parámetros en el método del controlador. Por ejemplo:

@GetMapping("/reporte")
@PreAuthorize("#origen == 'interno' and hasAuthority('REPORTES_VER')")
public ResponseEntity<Reporte> generarReporte(@RequestHeader("Origen") String origen) {
    Reporte reporte = reporteService.generar();
    return ResponseEntity.ok(reporte);
}

En este ejemplo, la expresión verifica que el header Origen tenga el valor 'interno' y que el usuario tenga la autoridad REPORTES_VER.

Para mejorar la legibilidad y el mantenimiento del código, es posible definir las expresiones en métodos de servicios o en beans de seguridad. Por ejemplo, utilizando un componente que encapsula las reglas de autorización:

@Component("controlAcceso")
public class ControlAcceso {

    public boolean puedeVerPedido(Long pedidoId, String username) {
        // Lógica para verificar si el usuario puede ver el pedido
        return pedidoService.esPropietario(pedidoId, username);
    }
}

Y en el controlador:

@GetMapping("/pedidos/{id}")
@PreAuthorize("@controlAcceso.puedeVerPedido(#id, principal.username)")
public ResponseEntity<Pedido> verPedido(@PathVariable Long id) {
    Pedido pedido = pedidoService.buscarPorId(id);
    return ResponseEntity.ok(pedido);
}

De esta manera, se delega la lógica de autorización a un componente dedicado, lo cual favorece la separación de responsabilidades y facilita las pruebas unitarias.

También es posible utilizar expresiones regulares y otras funciones dentro de las expresiones SpEL. Por ejemplo:

@GetMapping("/usuarios/email/{email}")
@PreAuthorize("#email matches '.+@dominio.com' and hasRole('SOPORTE')")
public ResponseEntity<Usuario> buscarPorEmail(@PathVariable String email) {
    Usuario usuario = usuarioService.buscarPorEmail(email);
    return ResponseEntity.ok(usuario);
}

Esta expresión permite que solo los usuarios del rol SOPORTE puedan buscar usuarios cuyo email pertenece al dominio dominio.com.

Es importante tener en cuenta que las expresiones SpEL se evalúan en tiempo de ejecución, por lo que deben ser eficientes y seguras. Evitar operaciones costosas o que puedan generar excepciones es fundamental para mantener el rendimiento de la aplicación.

Además, es recomendable manejar adecuadamente las excepciones de seguridad que puedan surgir al evaluar las expresiones. Spring Security se encarga de lanzar las excepciones correspondientes, pero es importante proporcionar respuestas adecuadas al cliente.

Combinar las expresiones SpEL con otros mecanismos de seguridad, como las anotaciones @Secured y @RolesAllowed, permite crear un sistema de seguridad robusto y flexible en los controladores de la aplicación.

Seguridad con expresiones SpEL en servicios y repositorios

En Spring Security, la aplicación de expresiones SpEL (Spring Expression Language) en servicios y repositorios permite definir reglas de autorización detalladas y adaptadas a la lógica de negocio. Al emplear anotaciones como @PreAuthorize, @PostAuthorize, @PreFilter y @PostFilter en estos componentes, se logra un control de acceso más granular, protegiendo métodos críticos y filtrando datos sensibles.

En los servicios, es común realizar operaciones que requieren verificar permisos específicos o validar condiciones sobre los datos. Al utilizar @PreAuthorize en métodos de servicio, se pueden evaluar expresiones antes de su ejecución para garantizar que solo usuarios autorizados puedan invocarlos. Por ejemplo:

@Service
public class CuentaService {

    @PreAuthorize("#cuenta.usuario.id == principal.id or hasRole('ADMIN')")
    public void actualizarSaldo(Cuenta cuenta, BigDecimal monto) {
        // Lógica para actualizar el saldo de la cuenta
    }
}

En este ejemplo, el método actualizarSaldo solo puede ser ejecutado por el propietario de la cuenta o por un usuario con rol ADMIN. La expresión SpEL #cuenta.usuario.id == principal.id compara el ID del usuario de la cuenta con el ID del usuario autenticado, representado por principal.id. De esta forma, se protege el método contra accesos no autorizados.

Las anotaciones @PostAuthorize también son útiles en servicios cuando se requiere validar el resultado de un método. Por ejemplo:

@PreAuthorize("hasRole('USUARIO')")
@PostAuthorize("returnObject.propietario.id == principal.id")
public Documento obtenerDocumento(Long id) {
    // Lógica para obtener el documento
    return documentoRepository.findById(id).orElseThrow();
}

Aquí, el método obtenerDocumento se asegura, después de su ejecución, de que el documento devuelto pertenece al usuario autenticado. La expresión SpEL returnObject.propietario.id == principal.id compara el propietario del documento con el usuario actual, garantizando que un usuario no pueda acceder a documentos ajenos.

En los repositorios de Spring Data, es posible definir filtros de seguridad a nivel de consultas mediante anotaciones como @PostFilter. Aunque su uso en repositorios es menos común, puede ser útil en casos donde se necesite filtrar resultados basados en criterios de seguridad. Por ejemplo:

@Repository
public interface PedidoRepository extends JpaRepository<Pedido, Long> {

    @PostFilter("filterObject.cliente.id == principal.id or hasRole('ADMIN')")
    List<Pedido> findAll();
}

Con esta configuración, al invocar findAll(), se devuelve una lista de pedidos que solo incluye aquellos pertenecientes al cliente autenticado, a menos que el usuario tenga el rol ADMIN. La expresión SpEL filterObject.cliente.id == principal.id filtra cada elemento de la lista en función del cliente asociado al pedido.

Es importante destacar que el uso de @PostFilter puede tener implicaciones de rendimiento, ya que el filtrado se realiza en memoria después de ejecutar la consulta. Para mejorar la eficiencia, es recomendable implementar filtros directamente en las consultas del repositorio utilizando métodos de consulta derivados o anotaciones @Query. Por ejemplo:

@Query("SELECT p FROM Pedido p WHERE p.cliente.id = :clienteId")
List<Pedido> findPedidosByClienteId(@Param("clienteId") Long clienteId);

En este caso, la restricción se aplica a nivel de base de datos, optimizando el rendimiento y evitando cargar en memoria datos innecesarios.

En servicios, también es posible utilizar @PreFilter y @PostFilter para filtrar colecciones de entrada o salida. Por ejemplo, si un método recibe una lista de entidades y se desea procesar solo aquellas que el usuario tiene permiso para modificar:

@Service
public class ProductoService {

    @PreFilter("filterObject.propietario.id == principal.id")
    public void actualizarProductos(List<Producto> productos) {
        // Lógica para actualizar los productos
    }
}

Aquí, antes de ejecutar actualizarProductos, la lista productos se filtra para incluir únicamente aquellos cuyo propietario coincide con el usuario autenticado. Esto evita que un usuario modifique productos que no le pertenecen.

Adicionalmente, se pueden crear métodos auxiliares en los servicios para reutilizar lógica de autorización y simplificar las expresiones SpEL. Por ejemplo:

@Service("permisoService")
public class PermisoService {

    public boolean esPropietario(Long entidadId) {
        // Lógica para verificar si el usuario autenticado es propietario de la entidad
    }
}

Y luego, en el servicio:

@Service
public class ProyectoService {

    @PreAuthorize("@permisoService.esPropietario(#proyecto.id)")
    public void eliminarProyecto(Proyecto proyecto) {
        // Lógica para eliminar el proyecto
    }
}

De esta manera, se promueve la reutilización de código y se mantiene una separación de responsabilidades, facilitando el mantenimiento y las pruebas unitarias.

Es esencial configurar correctamente el contexto de seguridad en las pruebas unitarias y de integración para validar que las expresiones SpEL funcionan según lo esperado. Al utilizar herramientas como Mockito y Spring Test, se pueden simular los detalles de autenticación y verificar los resultados de los métodos protegidos.

Por ejemplo, en una prueba unitaria:

@ExtendWith(SpringExtension.class)
public class CuentaServiceTest {

    @InjectMocks
    private CuentaService cuentaService;

    @Mock
    private SecurityContext securityContext;

    @Mock
    private Authentication authentication;

    @BeforeEach
    public void setup() {
        SecurityContextHolder.setContext(securityContext);
        when(securityContext.getAuthentication()).thenReturn(authentication);
        when(authentication.getPrincipal()).thenReturn(usuarioAutenticado);
    }

    @Test
    public void testActualizarSaldo() {
        // Configuración de la prueba y validación
    }
}

Es importante recordar que las expresiones SpEL en servicios y repositorios deben ser claras y evitar complejidad excesiva. Mantener las expresiones sencillas mejora la legibilidad y reduce el riesgo de errores. Además, siempre que sea posible, es preferible aplicar restricciones de seguridad en la capa de acceso a datos para aprovechar las optimizaciones de la base de datos.

Al aplicar Spring Security con expresiones SpEL en servicios y repositorios, se logra un sistema de seguridad robusto y flexible, alineado con la lógica de negocio y las necesidades de la aplicación. Esta estrategia permite definir políticas de acceso precisas y garantiza la protección de los recursos críticos, contribuyendo a la integridad y confidencialidad de los datos.

Aprende SpringBoot GRATIS online

Ejercicios de esta lección Autenticación y autorización con anotaciones

Evalúa tus conocimientos de esta lección Autenticación y autorización con anotaciones con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

API Query By Example (QBE)

Spring Boot
Test

Identificadores y relaciones JPA

Spring Boot
Puzzle

Borrar datos de base de datos

Spring Boot
Test

Web y Test Starters

Spring Boot
Puzzle

Métodos find en repositorios

Spring Boot
Test

Controladores Spring MVC

Spring Boot
Código

Inserción de datos

Spring Boot
Test

CRUD Customers Spring MVC + Spring Data JPA

Spring Boot
Proyecto

Backend API REST con Spring Boot

Spring Boot
Proyecto

Controladores Spring REST

Spring Boot
Código

Uso de Spring con Thymeleaf

Spring Boot
Puzzle

API Specification

Spring Boot
Puzzle

Registro de usuarios

Spring Boot
Test

Crear entidades JPA

Spring Boot
Código

Asociaciones en JPA

Spring Boot
Test

Asociaciones de entidades JPA

Spring Boot
Código

Integración con Vue

Spring Boot
Test

Consultas JPQL

Spring Boot
Código

Open API y cómo agregarlo en Spring Boot

Spring Boot
Puzzle

Uso de Controladores REST

Spring Boot
Puzzle

Repositorios reactivos

Spring Boot
Test

Inyección de dependencias

Spring Boot
Test

Introducción a Spring Boot

Spring Boot
Test

CRUD y JPA Repository

Spring Boot
Puzzle

Inyección de dependencias

Spring Boot
Código

Vista en Spring MVC con Thymeleaf

Spring Boot
Test

Servicios en Spring

Spring Boot
Código

Operadores Reactivos

Spring Boot
Puzzle

Configuración de Vue

Spring Boot
Puzzle

Entidades JPA

Spring Boot
Test

Integración con Angular

Spring Boot
Test

API Specification

Spring Boot
Test

API Query By Example (QBE)

Spring Boot
Puzzle

Controladores MVC

Spring Boot
Test

Anotaciones y mapeo en JPA

Spring Boot
Puzzle

Consultas JPQL con @Query en Spring Data JPA

Spring Boot
Test

Repositorios Spring Data

Spring Boot
Test

Inyección de dependencias

Spring Boot
Puzzle

Data JPA y Mail Starters

Spring Boot
Test

Configuración de Angular

Spring Boot
Puzzle

Controladores Spring REST

Spring Boot
Test

Configuración de Controladores MVC

Spring Boot
Puzzle

Consultas JPQL con @Query en Spring Data JPA

Spring Boot
Puzzle

Actualizar datos de base de datos

Spring Boot
Test

Verificar token JWT en peticiones

Spring Boot
Test

Login de usuarios

Spring Boot
Test

Integración con React

Spring Boot
Test

Configuración de React

Spring Boot
Puzzle

Todas las lecciones de SpringBoot

Accede a todas las lecciones de SpringBoot y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Spring Boot

Spring Boot

Introducción Y Entorno

Spring Boot Starters

Spring Boot

Introducción Y Entorno

Inyección De Dependencias

Spring Boot

Introducción Y Entorno

Controladores Spring Mvc

Spring Boot

Spring Web

Vista En Spring Mvc Con Thymeleaf

Spring Boot

Spring Web

Controladores Spring Rest

Spring Boot

Spring Web

Open Api Y Cómo Agregarlo En Spring Boot

Spring Boot

Spring Web

Servicios En Spring

Spring Boot

Spring Web

Clientes Resttemplate Y Restclient

Spring Boot

Spring Web

Rxjava En Spring Web

Spring Boot

Spring Web

Crear Entidades Jpa

Spring Boot

Persistencia Spring Data

Asociaciones De Entidades Jpa

Spring Boot

Persistencia Spring Data

Repositorios Spring Data

Spring Boot

Persistencia Spring Data

Métodos Find En Repositorios

Spring Boot

Persistencia Spring Data

Inserción De Datos

Spring Boot

Persistencia Spring Data

Actualizar Datos De Base De Datos

Spring Boot

Persistencia Spring Data

Borrar Datos De Base De Datos

Spring Boot

Persistencia Spring Data

Consultas Jpql Con @Query En Spring Data Jpa

Spring Boot

Persistencia Spring Data

Api Query By Example (Qbe)

Spring Boot

Persistencia Spring Data

Api Specification

Spring Boot

Persistencia Spring Data

Repositorios Reactivos

Spring Boot

Persistencia Spring Data

Introducción E Instalación De Apache Kafka

Spring Boot

Mensajería Asíncrona

Crear Proyecto Con Apache Kafka

Spring Boot

Mensajería Asíncrona

Creación De Producers

Spring Boot

Mensajería Asíncrona

Creación De Consumers

Spring Boot

Mensajería Asíncrona

Kafka Streams En Spring Boot

Spring Boot

Mensajería Asíncrona

Introducción A Spring Webflux

Spring Boot

Reactividad Webflux

Spring Data R2dbc

Spring Boot

Reactividad Webflux

Controlador Rest Reactivo Basado En Anotaciones

Spring Boot

Reactividad Webflux

Controlador Rest Reactivo Funcional

Spring Boot

Reactividad Webflux

Operadores Reactivos Básicos

Spring Boot

Reactividad Webflux

Operadores Reactivos Avanzados

Spring Boot

Reactividad Webflux

Cliente Reactivo Webclient

Spring Boot

Reactividad Webflux

Introducción A Spring Security

Spring Boot

Seguridad Con Spring Security

Seguridad Basada En Formulario En Mvc Con Thymeleaf

Spring Boot

Seguridad Con Spring Security

Registro De Usuarios

Spring Boot

Seguridad Con Spring Security

Login De Usuarios

Spring Boot

Seguridad Con Spring Security

Verificar Token Jwt En Peticiones

Spring Boot

Seguridad Con Spring Security

Seguridad Jwt En Api Rest Spring Web

Spring Boot

Seguridad Con Spring Security

Seguridad Jwt En Api Rest Reactiva Spring Webflux

Spring Boot

Seguridad Con Spring Security

Autenticación Y Autorización Con Anotaciones

Spring Boot

Seguridad Con Spring Security

Testing Unitario De Componentes Y Servicios

Spring Boot

Testing Con Spring Test

Testing De Repositorios Spring Data Jpa Y Acceso A Datos Con Spring Test

Spring Boot

Testing Con Spring Test

Testing Controladores Spring Mvc Con Thymeleaf

Spring Boot

Testing Con Spring Test

Testing Controladores Rest Con Json

Spring Boot

Testing Con Spring Test

Testing De Aplicaciones Reactivas Webflux

Spring Boot

Testing Con Spring Test

Testing De Seguridad Spring Security

Spring Boot

Testing Con Spring Test

Testing Con Apache Kafka

Spring Boot

Testing Con Spring Test

Integración Con Angular

Spring Boot

Integración Frontend

Integración Con React

Spring Boot

Integración Frontend

Integración Con Vue

Spring Boot

Integración Frontend

Accede GRATIS a SpringBoot y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Aprender qué anotaciones de seguridad existen
  • Saber aplicar anotaciones en métodos
  • Securizar métodos en controladores
  • Securizar métodos en servicios
  • Securizar métodos en repositorios