Я изучаю Spring Boot с помощью Spring Security, и у меня возникли проблемы с конечной точкой @PostMapping в моем AuthController. Конечная точка @GetMapping работает нормально, но конечная точка @PostMapping никогда не затрагивается. Я проверил запрос с помощью Postman, и все кажется правильным. Вот подробности:
Конфигурация безопасности (SecurityConfig):
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public UserDetailsService userDetailsService() {
// Define your custom UserDetailsService implementation
return new CustomUserDetailsService();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(req ->
req.requestMatchers(
"/auth/**",
"/css/**.css",
"/js/**"
).permitAll()
.anyRequest().authenticated()
)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
@RestController
@RequestMapping("/auth")
public class AuthController {
@GetMapping("/test")
public String test() {
return "Testing GET in Auth Ctrl.";
}
@PostMapping("/login")
public String login(@RequestBody AuthRequest authRequest) {
try {
if (authRequest.getUsername() == null || authRequest.getPassword() == null)
throw new AuthenticationException("AuthRequest is empty");
// Assuming successful authentication, you would normally return a JWT token here
return "Login successful!";
} catch (AuthenticationException e) {
return "Login failed!";
}
}
}
@Data
@NoArgsConstructor
class AuthRequest {
private String username;
private String password;
}
@Service
public class CustomUserDetailsService implements UserDetailsService {
private final Map<String, String> usersMap = new HashMap<>();
@Autowired
public CustomUserDetailsService() {
// Initialize the usersMap with encoded passwords
usersMap.put("ricky", "$2a$10$Dow1SE9N1XzFxXh3YDJIoO/b0Zi4DlCg8Up7X5DpIS9b/T/xkaHOO"); // password: 123
usersMap.put("martin", "$2a$10$Dow1SE9N1XzFxXh3YDJIoO/b0Zi4DlCg8Up7X5DpIS9b/T/xkaHOO"); // password: 456
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (usersMap.containsKey(username)) {
return new User(username, usersMap.get(username), new ArrayList<>()); // Empty authorities list
}
// If this is thrown, then we won't generate a JWT token.
throw new UsernameNotFoundException(username + " not found.");
}
}
Тестирование с помощью Postman:
URL: http://localhost:8080/auth/login Метод: ПОСТ Заголовки: Тип контента: application/json Тело: необработанный JSON. Пример тела:
{
"username": "ricky",
"password": "123"
}
Что я пробовал:
Проблема: Несмотря на описанные выше шаги, конечная точка @PostMapping никогда не попадает в систему, и сообщения об ошибках не регистрируются. Конечная точка @GetMapping работает нормально.
Дополнительная информация: pom.xml
Мы будем очень признательны за любые идеи или предложения о том, почему конечная точка @PostMapping не затрагивается!
403 Запрещено, контроль отладки никогда не достигает конечной точки входа в контроллер аутентификации.




ну, конечно, он не дойдет до вашего метода, если фильтр безопасности Spring возвращает запрещенный :)
вам также следует проверить, ПОЧЕМУ вы получаете 403, установить уровень ведения журнала для отладки с помощью logging.level.org.springframework.security=DEBUG, чтобы вы увидели ошибку.
Я готов поспорить, что именно CSRF правильно не позволяет вам отправлять «опасные» запросы (фактически любой другой запрос, кроме GET) без токена CSRF.
Настройте серверную часть для хранения токенов CSRF в файлах cookie.
http.csrf(csrf -> csrf.csrfTokenRepository
(CookieCsrfTokenRepository.withHttpOnlyFalse()));
Сначала вам следует отправить какой-то запрос (любой запрос), чтобы получить файл cookie CSRF (автоматически добавляется в ответ на вызов, у которого его еще нет) с именем (XSRF-TOKEN), а затем добавить значение этого файла. cookie в качестве заголовка X-XSRF-TOKEN вашего POST-вызова. Смотрите здесь
Если вы не используете файлы cookie для аутентификации и не используете сеанс, вы также можете рассмотреть возможность отключения CSRF, поскольку вам не нужна защита CSRF без сеанса / файлов cookie
http
.csrf(AbstractHttpConfigurer::disable)
// ...
Действительно спасибо за помощь. Но я сталкиваюсь со странной ошибкой, когда в AuthController происходит вызов authenticationManager.authenticate. Вот репозиторий [ссылка] (github.com/codesuman/spring-auth/blob/basic-security/src/main/… ). Подробности об ошибке: AuthenticationManager выдает StackOverflowError?
Пожалуйста, создайте новый вопрос, а затем пришлите мне ссылку, чтобы я мог посмотреть — я не могу давать ответы в комментариях (недостаточно места). Я отвечал на аналогичный вопрос неделю назад - посмотрите
Спасибо за помощь, проблема решена. AuthenticationProvider не был настроен и возвращал ноль — отсюда и исключение.
Возможно, потому, что ваш «/login» не разрешен в RequestMatchers. Вы должны разрешить там «/login», чтобы выполнить ваш запрос на публикацию.
Ваш ответ можно улучшить, добавив дополнительную вспомогательную информацию. Пожалуйста, отредактируйте , добавив дополнительную информацию, например цитаты или документацию, чтобы другие могли подтвердить правильность вашего ответа. Более подробную информацию о том, как писать хорошие ответы, вы можете найти в справочном центре.
Что значит «никогда не бить»? Какой код ответа HTTP вы получаете?