102 lines
4.1 KiB
Java
102 lines
4.1 KiB
Java
package es.tatvil.taiageweb.config;
|
|
|
|
import es.tatvil.taiageweb.servicio.UsuarioService;
|
|
import org.springframework.context.annotation.Bean;
|
|
import org.springframework.context.annotation.Configuration;
|
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
import org.springframework.security.web.SecurityFilterChain;
|
|
|
|
/**
|
|
* Configuración de seguridad de la aplicación.
|
|
*
|
|
* <p>Define las reglas de acceso HTTP, el proveedor de autenticación basado en
|
|
* base de datos y la configuración del formulario de login/logout.</p>
|
|
*
|
|
* <ul>
|
|
* <li>Rutas públicas: {@code /}, {@code /login}, {@code /registro}, {@code /leyes},
|
|
* {@code /noticias}, {@code /webhook/stripe} y recursos estáticos.</li>
|
|
* <li>Panel admin ({@code /admin/**}): requiere {@code ROLE_ADMIN}.</li>
|
|
* <li>Contenido de pago ({@code /curso/**}, {@code /api/**}): requiere
|
|
* {@code ROLE_PAGADO} o {@code ROLE_ADMIN}.</li>
|
|
* </ul>
|
|
*/
|
|
@Configuration
|
|
@EnableWebSecurity
|
|
public class SecurityConfig {
|
|
|
|
/**
|
|
* Crea el {@link PasswordEncoder} BCrypt usado en toda la aplicación.
|
|
*
|
|
* @return encoder BCrypt con factor de coste por defecto (10)
|
|
*/
|
|
@Bean
|
|
public PasswordEncoder passwordEncoder() {
|
|
return new BCryptPasswordEncoder();
|
|
}
|
|
|
|
/**
|
|
* Crea el proveedor de autenticación DAO que consulta {@link UsuarioService}.
|
|
*
|
|
* @param service servicio que implementa {@link org.springframework.security.core.userdetails.UserDetailsService}
|
|
* @param encoder encoder de contraseñas
|
|
* @return proveedor configurado
|
|
*/
|
|
@Bean
|
|
public DaoAuthenticationProvider authProvider(UsuarioService service, PasswordEncoder encoder) {
|
|
var provider = new DaoAuthenticationProvider(service);
|
|
provider.setPasswordEncoder(encoder);
|
|
return provider;
|
|
}
|
|
|
|
/**
|
|
* Define la cadena de filtros de seguridad HTTP.
|
|
*
|
|
* @param http objeto de configuración de Spring Security
|
|
* @return cadena de filtros construida
|
|
* @throws Exception si la configuración es inválida
|
|
*/
|
|
@Bean
|
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
http
|
|
.csrf(csrf -> csrf.ignoringRequestMatchers("/webhook/stripe"))
|
|
.headers(headers -> headers
|
|
.frameOptions(frame -> frame.sameOrigin())
|
|
)
|
|
.authorizeHttpRequests(auth -> auth
|
|
// Recursos públicos
|
|
.requestMatchers(
|
|
"/", "/inicio", "/login", "/registro",
|
|
"/leyes", "/noticias", "/acceso-denegado", "/error",
|
|
"/webhook/stripe",
|
|
"/css/**", "/js/**", "/images/**", "/leyes/**", "/audios/**", "/favicon.ico"
|
|
).permitAll()
|
|
// Panel de administración
|
|
.requestMatchers("/admin/**").hasRole("ADMIN")
|
|
// Contenido de pago
|
|
.requestMatchers("/curso", "/curso/**", "/planning", "/esquema.html", "/flashcards.html", "/flashcards/**", "/api/**").hasAnyRole("PAGADO", "ADMIN")
|
|
// Cualquier otra ruta requiere autenticación
|
|
.anyRequest().authenticated()
|
|
)
|
|
.formLogin(form -> form
|
|
.loginPage("/login")
|
|
.usernameParameter("email") // el campo del form se llama "email"
|
|
.defaultSuccessUrl("/", false)
|
|
.failureUrl("/login?error")
|
|
.permitAll()
|
|
)
|
|
.logout(logout -> logout
|
|
.logoutUrl("/logout")
|
|
.logoutSuccessUrl("/login?logout")
|
|
.permitAll()
|
|
)
|
|
.exceptionHandling(ex -> ex
|
|
.accessDeniedPage("/acceso-denegado")
|
|
);
|
|
return http.build();
|
|
}
|
|
}
|