Я работаю над веб-приложением с пружинной загрузкой и настроил Spring Security с помощью JWT. Моя проблема в том, что когда я делаю запрос POST в Postman, я получаю ошибку 401 Unauthorized. Однако когда я делаю запрос GET, он возвращает данные со статусом 200. Кажется, это обычная проблема; Я проверил разные потоки stackoverflow, и большинство из них предлагают отключить CSRF в конфигурации безопасности. Я это уже сделал, но все равно не работает.
Запрос «/courses/**» с помощью PermitAll() должен быть доступен без аутентификации.
SecurityConfig.java
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final CustomUserDetailsService userDetailsService;
private final JwtAuthEntryPoint jwtAuthEntryPoint;
@Bean
public AuthTokenFilter authenticationTokenFilter(){
return new AuthTokenFilter();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
@Bean
public DaoAuthenticationProvider authenticationProvider(){
var authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.csrf(AbstractHttpConfigurer::disable) // Disable CSRF for stateless APIs
.exceptionHandling(exception -> exception.authenticationEntryPoint(jwtAuthEntryPoint))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth->
auth.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/roles/**").permitAll()
.requestMatchers("/api/users/**").permitAll()
.requestMatchers("/courses/**").permitAll()
.anyRequest().authenticated()
);
http.authenticationProvider(authenticationProvider());
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Почтовый метод
@PostMapping("/add-course")
public ResponseEntity<?> addCourse(@RequestBody Course course){
try{
System.out.println("Course body: " + course);
Course theCourse = courseService.addNewCourse(course);
return ResponseEntity.ok(theCourse);
}catch (Exception e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
Изображение вызова API Postman
Рассмотрите возможность тестирования запроса POST, временно разрешив все запросы.
(.requestMatchers("/**").permitAll())
чтобы проверить, сохраняется ли проблема. Это поможет определить, связана ли проблема с вашей конфигурацией /courses/**
.
Научитесь использовать уценку для форматирования своих публикаций.
Это предложение сработало, я также попробовал предложение Виджая, а также внес некоторые изменения в код. POST-запрос теперь работает как положено. Спасибо!
Я хотел бы использовать цепочку конфигураций вместо отдельной конфигурации.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
return http.csrf(AbstractHttpConfigurer::disable) // Disable CSRF for stateless APIs
.exceptionHandling(exception -> exception.authenticationEntryPoint(jwtAuthEntryPoint))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeHttpRequests(auth->
auth.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/roles/**").permitAll()
.requestMatchers("/api/users/**").permitAll()
.requestMatchers("/courses/**").permitAll()
.anyRequest().authenticated()
).build();
}
Это гарантирует, что конфигурация применяется в одной плавной цепочке, и позволяет избежать проблем с несколькими вызовами http.build().
Спасибо за ответ. Я внес некоторые изменения в код, использовал CourseDto для сохранения курса вместо прямой передачи объекта Course и воспользовался предложением Виджая Кумара использовать связанную конфигурацию вместо отдельной конфигурации.
POST-запрос теперь работает как положено. Проверьте прикрепленное изображение ниже.
Почтовый метод POSTMAN
Вы написали (в своем ответе): Я внес некоторые изменения в код. Возможно, вы могли бы отредактировать свой ответ и опубликовать эти изменения, поскольку они могут помочь другим, испытывающим аналогичные проблемы.
Рад, что смог помочь.
@Abra, я думаю, другие изменения не имеют прямого отношения к исходному вопросу.
Просто предположение, но попробуйте удалить косую черту из «/add-course» в PostMapping.