I am trying to configure Spring Security in a Spring Boot application for my REST API with basic authentication as follows:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig{
@Autowired
private ClienteServiceImpl clienteServiceImpl;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{
return httpSecurity
.csrf((csrf) -> csrf.disable())
.httpBasic(Customizer.withDefaults())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(http -> {
// Endpoints publicos
http.requestMatchers(HttpMethod.GET, "/api/v2/hola").permitAll();
http.requestMatchers(HttpMethod.POST, "/api/v2/cliente").permitAll();
// Endpoints seguros
http.requestMatchers(HttpMethod.GET, "/api/v2/hola-secured").hasAnyAuthority("CREATE", "READ", "UPDATE", "DELETE");
http.requestMatchers(HttpMethod.GET, "/api/v2/hola-secured").hasAnyRole("ADMIN", "USER");
// Endpoints no especificados
http.anyRequest().denyAll();
})
.build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public AuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(this.clienteServiceImpl);
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
My service is:
@Service
public class ClienteServiceImpl implements ClienteService, UserDetailsService{
@Autowired
private ClienteRepository clienteRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
ClienteEntity clienteEntity = clienteRepository.findClienteEntityByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + email));
List<SimpleGrantedAuthority> authorityList = new ArrayList<>();
clienteEntity.getRoles()
.forEach(role -> authorityList.add(new SimpleGrantedAuthority("ROLE_".concat(role.getNombre()))));
clienteEntity.getRoles().stream()
.flatMap(role -> role.getPermissionList().stream())
.forEach(permission -> authorityList.add( new SimpleGrantedAuthority(permission.getName())));
User user = new User(
clienteEntity.getEmail(),
clienteEntity.getPassword(),
clienteEntity.isEnabled(),
clienteEntity.isAccountNoExpired(),
clienteEntity.isAccountNoLocked(),
clienteEntity.isCredentialNoExpired(),
authorityList
);
return user;
}
}
This is my SecurityConfig file, where I have configured basic authentication with a user and password in memory. However, when I try to access my protected endpoints, Spring Security keeps asking for authentication credentials.
Can anyone help me understand what I’m doing wrong or what I’m missing in my configuration to make the authentication work properly?
Any help would be greatly appreciated.