Buona sera programmatori,
Sono alle prese con la configurazione di Spring Security e ne sto studiando il funzionamento.
Sapete darmi un indicazione su come procedere:
In primis vorrei che mi comparisse un mio FORM di LOGIN quando invece compare sempre e solo quello di default.
Al momento l' APP chiede per ogni indirizzo di accesso di loggarsi tramite form generico.
Vi posto il codice descrivendolo,
Ho caricato la dipendenza:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Nel package: "src/main/java/com/app/x/configuration/" ho la classe: SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final CustomUserDetailsService customUserDetailsService;
public SecurityConfig(CustomUserDetailsService customUserDetailsService) {
this.customUserDetailsService = customUserDetailsService;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll() // Public endpoints
.anyRequest().authenticated() // Secure all other endpoints
)
.formLogin(form -> form
.loginPage("/login") // Custom login page URL (L' url corrisponde)
.permitAll() // Allow everyone to access the login page
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/public/home") // Redirect after logout
.permitAll()
);
return http.build();
}
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder())
.and()
.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // Solo per test, usa BCrypt in produzione
}
}
-----------------------------------------------------------------------------------------------------------------
Nel Service(src/main/java/com/app/x/configuration) ho invece quest'altra classe di TEST:
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Simulazione di un utente in memoria
if ("user".equals(username)) {
return User.withUsername("user")
.password("{noop}password") // {noop} indica che non usiamo codifica
.roles("USER")
.build();
} else {
throw new UsernameNotFoundException("Utente non trovato");
}
}
}
------------------------------------------------------------------------------------------------------------------------
Nel Controller:
@GetMapping("/login") public String loginPage(@RequestParam(value = "error",
required = false) String error, Model model) {
if (error != null) {
model.addAttribute("errorMessage", "Username o password non validi.");
}
return "login";
}
Il modello serve a Thymeleaf per riportare l'errore nel FORM.