Форум программистов, компьютерный форум, киберфорум
Java: Spring, Spring Boot
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 09.06.2019
Сообщений: 89

Почему при отправке запроса на http://localhost:8080/login не приходит ответ с токенами?

14.04.2025, 14:31. Показов 2106. Ответов 6

Студворк — интернет-сервис помощи студентам
Добрый день! Делал проект по статье - https://habr.com/ru/articles/865180/ и возник вопрос. При попытке отправить запрос на http://localhost:8080/login с json через Postman прилетает ответ в виде ошибки 401, но при этом в базе токены добавляются. SecureConfig я настроил и разрешения все даны на отправку запросов. Кто может помочь, почему при отправке запроса на http://localhost:8080/login не приходит ответ с токенами?

Проект Spring прикладываю


Отправка Post запроса с Json на регистрацию (http://localhost:8080/registration):
JSON
1
2
3
4
5
{
    "email":"test@mail.ru",
    "username":"test",
    "password": "1234567890"
}
Ответ 200: регистрация прошла успешно

Отправка Post запроса с Json на авторизацию (http://localhost:8080/login):
JSON
1
2
3
4
{
    "username":"test",
    "password": "1234567890"
}
Ответ 401: Unauthorized

Secure Config
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@Configuration
@EnableWebSecurity
public class SecurityConfig {
 
    private final JwtFilter jwtFIlter;
 
    private final UserService userService;
 
    private final CustomAccessDeniedHandler accessDeniedHandler;
 
    private final CustomLogoutHandler customLogoutHandler;
 
    public SecurityConfig(JwtFilter jwtFIlter,
                          UserService userService,
                          CustomAccessDeniedHandler accessDeniedHandler, CustomLogoutHandler customLogoutHandler) {
        this.jwtFIlter = jwtFIlter;
        this.userService = userService;
        this.accessDeniedHandler = accessDeniedHandler;
        this.customLogoutHandler = customLogoutHandler;
    }
 
 
    /**
     * Этот метод создает и настраивает цепочку фильтров безопасности для HTTP.
     *
     * @param http объект HttpSecurity для настройки цепочки фильтров безопасности
     * @return созданная цепочка фильтров безопасности
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 
        http.csrf(AbstractHttpConfigurer::disable); // Отключаем защиту от CSRF
 
        // Настраиваем авторизацию запросов
        http.authorizeHttpRequests(auth -> {
                    auth.requestMatchers("/login/**","/registration/**", "/css/**", "/refresh_token/**", "/")
                            .permitAll(); // Разрешаем все запросы к этим URL
                    auth.requestMatchers("/admin/**").hasAuthority("ADMIN"); // Разрешаем запросы только для администратора
                    auth.anyRequest().authenticated(); // Требуем аутентификацию для всех остальных запросов
                }).userDetailsService(userService)
                .exceptionHandling(e -> {
                    e.accessDeniedHandler(accessDeniedHandler); // Обработчик отказа доступа
                    e.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)); // Входная точка аутентификации
                })
                .sessionManagement(session -> session.sessionCreationPolicy(STATELESS)) // Управление сессиями
                .addFilterBefore(jwtFIlter, UsernamePasswordAuthenticationFilter.class) // Добавление фильтра JWT перед фильтром UsernamePasswordAuthenticationFilter
                .logout(log -> {
                    log.logoutUrl("/logout"); // URL для выхода
                    log.addLogoutHandler(customLogoutHandler); // Добавление пользовательского обработчика выхода
                    log.logoutSuccessHandler((request, response, authentication) ->
                            SecurityContextHolder.clearContext()); // Очистка контекста безопасности после успешного выхода
                });
 
        return http.build();
    }
 
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
 
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
 
}
Вложения
Тип файла: zip token.zip (59.7 Кб, 7 просмотров)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.04.2025, 14:31
Ответы с готовыми решениями:

Spring boot ошибка 500 при GET http://localhost:8080/doctors/2
package org.example.web.controller; import org.example.web.dto.DoctorDto; import...

Error running tomcat: Address localhost:8080 is already in use
Error running tomcat: Address localhost:8080 is already in use Этот порт я использовал в...

Не удается зайти на localhost:8080
Всем привет! Столкнулся с проблемой при запуске tomcat7. Выдает окно авторизации и я вообще понятия...

6
02.05.2025, 20:10

Не по теме:

Ответ ИИ
Анализ проблемы и рекомендации по исправлению

Проблема

При отправке POST-запроса на /login сервер возвращает ошибку 401 (Unauthorized),
хотя токены успешно сохраняются в базу данных. Это означает,
что процесс аутентификации проходит успешно, но ответ клиенту формируется некорректно.

Возможные причины

Ошибка в конфигурации JWT-фильтра: Возможно, фильтр неправильно обрабатывает успешную аутентификацию
и не добавляет токены в заголовки ответа.


Ошибочная конфигурация endpoint'а /login:
Возможно, логика обработки запроса на этот endpoint реализована неверно,
и токены не возвращаются клиенту.


Проблемы с возвращаемым статусом ответа:
Даже если токены генерируются правильно, статус ответа всё равно остается 401,
что сбивает клиента с толку.

Рекомендации по устранению проблемы

Шаг 1: Проверка реализации контроллера LoginController


Убедитесь, что ваш контроллер, обрабатывающий путь /login, корректно формирует ответ с токеном.

Вот пример простого контроллера:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@RestController
@RequestMapping("/api/auth")
public class AuthController {
 
    @Autowired
    private AuthenticationManager authenticationManager;
 
    @Autowired
    private TokenProvider tokenProvider;
 
    @PostMapping("/login")
    public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
        try {
            String username = loginRequest.getUsername();
            String password = loginRequest.getPassword();
            
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password));
        
            SecurityContextHolder.getContext().setAuthentication(authentication);
    
            String jwt = tokenProvider.generateToken(authentication);
    
            return ResponseEntity.ok(new JwtResponse(jwt));
        } catch (AuthenticationException ex) {
            throw new BadCredentialsException(ex.getMessage());
        }
    }
}
Шаг 2: Проверьте реализацию JWT Filter

Ваш JWT-фильтр должен добавлять токен в заголовки ответа при успешной аутентификации.
Убедитесь, что эта логика присутствует и работает верно:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component
public class JwtFilter extends OncePerRequestFilter {
 
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        if ("POST".equals(request.getMethod()) && "/login".equals(request.getServletPath())) {
            // Здесь должна происходить обработка запроса на /login
            // Например, проверка учетных данных и создание токена
            // Если все прошло успешно, добавьте токен в ответ
            String token = generateJwtToken(request);
            response.setHeader("Authorization", "Bearer " + token);
        }
        chain.doFilter(request, response);
    }
 
    private String generateJwtToken(HttpServletRequest request) {
        // Логика генерации токена
        return "";
    }
}
Шаг 3: Проверьте обработку ошибок

Проверьте логику вашего кастомного обработчика исключений (CustomAccessDeniedHandler) и убедитесь,
что при ошибке 401 возвращается именно та ошибка, которую ожидает клиент. Вероятнее всего,
проблема кроется в формировании статуса ответа — возможно, код пытается вернуть ошибку даже тогда, когда данные валидные.

Пример правильной обработки ошибок:


Java
1
2
3
4
5
6
7
8
9
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
 
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exception) 
    throws IOException, ServletException {
        response.sendError(HttpStatus.FORBIDDEN.value(), "Доступ запрещён");
    }
}
Шаг 4: Проверка настроек Authentication Manager

Настройки вашей конфигурации безопасности должны учитывать правильный способ проверки учетных данных.
Ваш текущий конфиг выглядит корректно, однако обратите внимание на то, как создается экземпляр AuthenticationManager.
Обычно достаточно такой простой реализации:

Java
1
2
3
4
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
    return config.getAuthenticationManager();
}

Для решения проблемы проверьте следующие моменты:

Реализация контроллера /login: проверяйте, что ответ действительно включает токен.
Реализация JWT-фильтра: убедившись, что токен добавляется в заголовки ответа.
Правильная настройка возврата статуса 401: убедитесь, что статус меняется на 200 при успешной аутентификации.
Подходящее поведение при обработке ошибок: наличие правильной реакции на исключения.

Эти шаги позволят вам устранить проблему и обеспечить правильное формирование ответа с токенами.

0
Модератор
Эксперт Java
 Аватар для alecss131
2843 / 1352 / 403
Регистрация: 11.08.2017
Сообщений: 4,321
Записей в блоге: 2
02.05.2025, 21:23
vvm28, Выглядит как ответ ИИ, на этот счет есть правила форума, а именно
7. Об использовании ИИ.
1. Использование ИИ для ответов на форуме запрещено. Форум - только для общения людей.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3391 / 2715 / 574
Регистрация: 04.09.2018
Сообщений: 8,534
Записей в блоге: 3
03.05.2025, 04:38
Цитата Сообщение от vvm28 Посмотреть сообщение
Вот пример простого контроллера:
У ТС проблема с конфигурацией через Spring...
vvm28, не надо вот эту ИИ-шную хрень сюда выкладывать.

Добавлено через 2 минуты
Fantan4ik, ответ 401 понятно, а трейс что пишет?
0
0 / 0 / 0
Регистрация: 09.06.2019
Сообщений: 89
05.05.2025, 15:49  [ТС]
При отправке запроса на http://localhost:8080/login выдает:

"2025-05-05T15:46:30.957+03:00 WARN 12584 --- [JWTAuthentication] [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNot AcceptableException: No acceptable representation]"

Добавлено через 2 минуты
С ИИ уже общался, ничем помочь не смог. Поэтому и обратился на форум
0
 Аватар для snajper_ro
116 / 101 / 52
Регистрация: 14.09.2011
Сообщений: 696
Записей в блоге: 1
07.06.2025, 12:57
spring-security-sample-dev.zip Можешь изучить наш пример рабочий, он работает.
1
0 / 0 / 0
Регистрация: 29.12.2025
Сообщений: 5
29.12.2025, 23:23
Цитата Сообщение от Fantan4ik Посмотреть сообщение
"2025-05-05T15:46:30.957+03:00 WARN 12584 --- [JWTAuthentication] [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNot AcceptableException: No acceptable representation]"
Вы отправляется тело запроса не в том формате - spring говорит именно об этом. Нужно отправлять запрос с Content-Type: application/json, так как, по умолчанию, использование аннотации @RequestBody подразумевает именно такой заголовок тела запроса.

Java
1
2
3
4
@PostMapping("/login")
    public ResponseEntity<AuthenticationResponseDto> authenticate(
            @RequestBody LoginRequestDto request
    ) {...}
Пример запроса и ответа.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
POST http://localhost:8080/login
Content-Type: application/json
Content-Length: 47
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2025.2.5
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*
 
{
  "username": "test",
  "password": "12345"
}
 
-------------------------------------------------------------------------------------------
 
HTTP/1.1 200 
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 29 Dec 2025 20:08:59 GMT
 
{
  "refreshToken": "eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNzY3MDM4OTM5LCJleHAiOjE3NjcyOTA5Mzl9.fsw5oMEdr-s5v_cNJ4xxh4ovCNRbWOjPKrquZDBfeE9_pr3VkhS2hK9MtOIBOiqL",
  "accessToken": "eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNzY3MDM4OTM5LCJleHAiOjE3NjcwNzQ5Mzl9.h_LqK88VX9plVJd9fCGR-yMBr2ZoFe3UICTNR5vkQH1iS0BMdUhrdEstJ8KPD7xu"
}
Надо очень внимательно следить за Content-Type заголовком, так как это единственный заголовок, который требует 100% корректности ввода.

Именно благодаря ему сервер понимает, в каком формате отправляются данные и как их нужно парсить. Если вы отправляете Content-Type: text\plain, а сервер ждет Content-Type: application/json, то вы друг друга просто не поймете.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.12.2025, 23:23
Помогаю со студенческими работами здесь

POST запрос на получение токена посредством HttpUrlConnection
Мне необходимо получить доступ из Java приложения к RESTful веб сервису, использующему...

Starting of Tomcat failed, the server port 8080 is already in use
люди,подскажите кто знает.установил томкэт,в нетбинсе указал что буду использовать внешний...

Eclipse & tomcat 8080 8009. Ports already in use
Никак не могу настроить сервер, вот такие ошибки

Как прицепить класс Spring MVC Controller к классу производному от httpServlet с нестандартным портом (8090 вместо 8080)
У меня есть задача организовать сервис оплат через сервис ЯНДЕКС-ДЕНЬГИ. Но тут возникают проблема...

HTTP запрос через Apache HTTP Client ничего не возвращает
У меня есть один сайт. Простой сайт на php. И есть второй сайт, где используется java на JBoss. Я...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru