I am working on a Spring boot backend app and I did a new Configuration to add a securityFilterChain
Here is my code
@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {
private final UserCheckingService userService;
private final JwtFilter jwtFilter;
public SecurityConfig(UserCheckingService userService,JwtFilter jwtFilter) {
this.userService = userService;
this.jwtFilter = jwtFilter;
}
@Bean
public PasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.csrf(AbstractHttpConfigurer::disable)
.addFilterBefore(
this.jwtFilter,
UsernamePasswordAuthenticationFilter.class
)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers( POST,"/auth").permitAll() // We will authenticate the user
.requestMatchers(POST,"/user/create").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(session->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public AuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(this.userService);
daoAuthenticationProvider.setPasswordEncoder(this.bCryptPasswordEncoder());
return daoAuthenticationProvider;
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("http://localhost:4200"); // Ajoutez vos origines autorisées
configuration.addAllowedMethod("*");
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Note that I added CORS Configuration for test purpose and it still doesn't work.
Here is my RestController
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "http://localhost:4200")
public class UserController implements DefaultController<User> {
@Autowired
private UserCheckingService userService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtService jwtService;
@PostMapping("/auth")
public Map<String, String> connect(@RequestBody User user){
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(user.getLogin().toString(), user.getPassword())
);
if(authentication.isAuthenticated()){
return jwtService.generateToken(user.getLogin().getLogin());
}
return null;
}
}
And I have a JWT Service but It won't help to solve my problem.
My problem :
I tried to connect using /user/auth with Postman (and it worked) I tried to connect using Angular by setting anyRequest().permitAll() in my securityFilterChain (and it worked)
and then I tried to do the same by setting anyRequest().authenticated()
And it didn't worked.
I am wondering why... Here is my JS Error
Access to XMLHttpRequest at 'http://localhost:8080/user/auth' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
error: ProgressEvent {isTrusted: true, lengthComputable: false, loaded: 0, total: 0, type: 'error', …}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}
message: "Http failure response for http://localhost:8080/user/auth: 0 Unknown Error"
name: "HttpErrorResponse"
ok:false
status: 0
statusText: "Unknown Error"
url: "{localhostURL}"
POST http://localhost:8080/user/auth net::ERR_FAILED 403 (Forbidden)
It is very weird because when I start debugging, my request goes in doFilterInternal() in my JWTFilter and I am not sure it is supposed to do it...
Also, here is my PostMan :
curl --location 'http://localhost:8080/user/auth' \
--header 'Content-Type: application/json' \
--data-raw '{
"login": "myLogin",
"password": "myPwd"
}'
I think my SpringBoot app wait for me to have a token for my user/auth request but I don't know how to disable it (I thought .requestMatchers( POST,"/auth").permitAll() would do the job)
I don't think this is a CORS Policy problem because when I don't restrict to authenticated my requests, it works
Thanks for helping me and sorry for my bad english I did my best ;)