Garantice la seguridad de su aplicación Spring aprovechando las sólidas funciones que ofrece el marco Spring Security.
El marco Spring Security protege su aplicación a través de autenticación y autorización. En su estado predeterminado, Spring Security garantiza que cada ruta (o página) de solicitud HTTP en su aplicación requiera la autenticación de un solo usuario global.
Este marco también es extremadamente flexible. Le permite crear reglas de seguridad personalizadas para cada ruta de solicitud HTTP en su aplicación, así como para los diferentes usuarios. Por lo tanto, puede eliminar la restricción de seguridad en las páginas que no requieren la autorización del usuario (como una página de inicio). Y establezca los roles y las autoridades de tipos de usuarios específicos.
Agregando Spring Security a su aplicación
Hay dos formas de agregar Spring Security a su aplicación. Puede seleccionarlo como una dependencia al generar una nueva aplicación Spring Boot usando Spring initializr, o agréguelo a su archivo de especificación de compilación en la sección de dependencia después de generar su proyecto.
Si seleccionó una de las opciones del proyecto Gradle, el archivo de dependencias se construir.gradle. Sin embargo, si elige Maven, entonces ese archivo es pom.xml.
Su construir.gradle El archivo debe contener la siguiente dependencia:
dependencies {
implementation 'org.springframework.boot: spring-boot-starter-security'
}
mientras tu pom.xml El archivo debe contener la siguiente dependencia:
org.springframework.boot
spring-boot-starter-security
La aplicación de muestra utilizada en el artículo está disponible en este repositorio GitHub y es gratis para su uso bajo la licencia MIT.
Uso de seguridad de primavera
Una vez que agregue la dependencia de Spring Security a su aplicación, puede comenzar a usar el marco inmediatamente. Simplemente ejecute su aplicación y luego navegue a la página de inicio de Spring Boot (o cualquier página de su aplicación). La aplicación de ejemplo utiliza el siguiente controlador inicial para controlar el valor predeterminado de Spring Boot. servidor local: 8080 pedido:
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
publicclassWebController{
@GetMapping("/")
public String home(){
return"Welcome!";
}
}
Ejecutar su aplicación después de agregar la clase de controlador único anterior genera la siguiente vista inicial:
Notarás que automáticamente te dirige a la anfitrión local: 8080/iniciar sesión y lo hace antes de permitirle acceder a cualquier otra página de la aplicación. En esta etapa, deberá proporcionar el nombre de usuario predeterminado (que es el usuario) y la contraseña generada automáticamente (que encontrará en la consola). La consola generará una línea como la siguiente:
Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81
Cada vez que reinicie su aplicación, la contraseña generada automáticamente cambiará, pero el nombre de usuario seguirá siendo el mismo. Ingresar el nombre de usuario y la contraseña predeterminados lo dirigirá a la vista adecuada en su aplicación.
Personalización de la seguridad de Spring
Para personalizar la seguridad de su aplicación, deberá anular la configuración predeterminada de Spring Security. Pero antes de eso (asumiendo que ya tiene Spring Web) necesitará varias otras dependencias para esta aplicación de muestra:
- JPA de datos de primavera
- Controlador MySQL JDBC
- hoja de tomillo
- Lombok
El marco Thymeleaf generará diferentes vistas. Lombok ayudará a reducir el código en sus clases de objetos. La biblioteca JPA y el controlador MySQL le permitirán usar una base de datos MySQL con la aplicación, pero tiene la opción de usar cualquier base de datos con la que se sienta cómodo. Usar una base de datos significa configurar el aplicaciones.propiedades archivo bajo el archivo de recursos.
spring.datasource.url=jdbc: mysql://${MYSQL_HOST: localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
El código de configuración anterior le permite conectarse a una base de datos MySQL local llamada primavera_seguridad, con un nombre de usuario de raíz, y contraseña (1234). Deberá actualizar estos datos para que coincidan con el nombre y las credenciales de su base de datos.
Después de agregar sus dependencias adicionales y crear su base de datos, puede comenzar a decidir cuántas vistas tendrá su aplicación. También necesitará saber cómo es la seguridad de cada página. Nuestra aplicación de muestra tiene 6 vistas:
- Página de inicio
- Página de registro
- Página de inicio de sesión
- Página de cierre de sesión
- Página de usuario
- Página de error
La única vista que requerirá la autorización del usuario es la página del usuario. Esta página solo es accesible para los usuarios que primero se registran y luego inician sesión en la aplicación. Además del paquete predeterminado de Spring Boot, deberá crear otros cuatro paquetes en su aplicación.
La clase de controlador de registro
El paquete del controlador contendrá las clases que manejan las solicitudes HTTP. Dependiendo de la función de una página, generalmente puede agrupar cada solicitud HTTP en una clase de controlador, como es el caso con el WebController clase. Sin embargo, la vista de registro tiene funciones más exclusivas, por lo que puede tener una clase de controlador privado:
@Controller
@RequestMapping("/register")
publicclassRegistrationController{
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
publicRegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder){
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm(){
return"registration";
}
@PostMapping
public String processRegistration(RegistrationForm form){
userRepo.save(form.toUser(passwordEncoder));
return"redirect:/login";
}
}
El Controlador de registro class es una puerta de entrada al aspecto de seguridad de su aplicación. El @RequestMapping anotación especifica el tipo de solicitud que manejará este controlador (solicitudes a servidor local: 8080/registro).
El @GetMapping anotación simplemente indica que si la aplicación recibe una solicitud de /register, el formulario de inscripción() El método debe manejar esa solicitud devolviendo la vista de registro.
Después de que un visitante haga clic en el botón de registro, entonces el @PostMapeo entra en juego la anotación. El procesoRegistro() El método le permite publicar los datos de usuario que obtiene del Formulario de inscripción clase a la base de datos, usando el Repositorio de usuarios clase. Pero antes de almacenar estos datos, el procesoRegistro() El método encripta la contraseña del usuario usando MuellesCodificador de contraseña interfaz.
Creación de nuevas configuraciones de seguridad
Desde Spring 3.1, los desarrolladores ahora pueden crear configuraciones para Spring Security utilizando Java, lo que significa clases en lugar de XML. Lo principal que requieren estas clases de configuración es la @Configuración anotación.
@Configuration
publicclassSecurityConfiguration{
}
El @Configuración La anotación indica que la clase anterior es una clase de configuración. Estas clases proporcionan frijoles al Contexto de la aplicación Spring, que es un contenedor que Spring usa para crear y administrar los diferentes componentes (o beans) de una aplicación. El primer frijol en el SeguridadConfiguración la clase es la Codificador de contraseña frijol.
@Bean
public PasswordEncoder passwordEncoder(){
returnnew BCryptPasswordEncoder();
}
El Controlador de registro la clase usa el Codificador de contraseña bean para codificar nuevas contraseñas antes de guardarlas en la base de datos. Otro frijol importante que deberá agregar al SeguridadConfiguración la clase es la usuarioDetallesServicio frijol.
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo){
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
thrownew UsernameNotFoundException("Customer '" + username + "' not found");
};
}
El usuarioDetallesServicio frijol emplea seguridad de primaveraServicio de detalles de usuario interfaz para recuperar el nombre de usuario y la contraseña de un usuario para la autenticación, durante la sesión de inicio de sesión de un cliente. Entonces, tan pronto como un cliente haga clic en el botón de inicio de sesión en la vista de inicio de sesión, el usuarioDetallesServicio el frijol se pone en movimiento.
A través de Repositorio de usuarios, el usuarioDetallesServicio bean obtiene acceso a todos los clientes existentes en la base de datos. Esta interfaz entonces utiliza el Repositorio de usuarios para ubicar a un usuario con un nombre de usuario y contraseña coincidentes, luego devuelve todos los atributos de este cliente como un objeto.
Si el objeto devuelto es un cliente, este cliente obtiene acceso a la aplicación. De lo contrario, la página se actualizará automáticamente y permitirá al usuario ingresar credenciales válidas.
La cadena de filtros
seguridad de primaveraSecurityFilterChain la interfaz es útil interfaz de programación de aplicaciones (API) que juega un papel esencial en la configuración de Spring Security. Esta interfaz funciona con seguridad de primaveraHttpSeguridad class para crear una cadena de filtros para solicitudes HTTP específicas.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http)throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin -> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout -> logout.logoutSuccessUrl("/logout"));
return http.build();
}
El cadena de filtros bean arriba usa el SecurityFilterChain API para realizar varias tareas. Primero, utiliza el HttpSeguridad clase para dictar que solo los usuarios que tienen el rol de USUARIO pueden acceder servidor local: 8080/usuario. Y un usuario obtiene este rol después del registro, gracias a la obtenerAutoridades() método que implementa cada nuevo objeto de cliente.
@Override
public Collection extends="extends" grantedauthority="grantedauthority"?> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
La cadena de filtros permite el acceso no autenticado a todas las demás URL de la aplicación. El cadena de filtros bean también utiliza el formularioIniciar sesión() y cerrar sesión() métodos de la HttpSeguridad objeto de clase.
Estos métodos le permiten dirigir automáticamente a un usuario a páginas específicas después de realizar una tarea. Entonces, un usuario que ingresa las credenciales correctas y hace clic en el botón de inicio de sesión en el /login la página se dirigirá automáticamente a la /user página.
Finalmente, el cadena de filtros bean construye y devuelve la cadena de filtros, lo que permite a los usuarios autorizados acceder a la aplicación. Los tres frijoles en el SeguridadConfiguración trabajar juntos en clase para asegurar su aplicación.
sin embargo, el cadena de filtros bean juega el papel más importante de dictar el nivel de autorización para cada solicitud HTTP. A medida que comience a agregar más páginas a su aplicación, puede usar el cadena de filtros bean para establecer su nivel de seguridad.
El principal beneficio de Spring Security
Spring Security le brinda control completo no solo sobre quién tiene acceso a su aplicación, sino también sobre el tipo de acceso que puede tener un usuario (a través de su función de roles de usuario). El control de acceso es uno de los aspectos más importantes de cualquier aplicación. Dar a los usuarios generales acceso sin filtrar a su aplicación debido a las barreras de control de acceso limitadas puede resultar un error costoso.