API не может получить доступ к частным конечным точкам (403 запрещено), даже если пользователь прошел аутентификацию

Я думаю, что не так, это мой фильтр аутентификации.

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    final String token = getTokenFromRequest(request);
    final String username;
    if (token == null) {
        filterChain.doFilter(request, response);
        return;
    }
    username = jwtService.getUsernameFromToken(token);
    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (jwtService.isTokenValid(token, userDetails)) {
            UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                    userDetails,
                    null,
                    userDetails.getAuthorities());
            authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authToken);
        }
    }
    filterChain.doFilter(request, response);
}

Сведения о пользователе добавляются в контекст безопасности, как и ожидалось, но затем doFilter все портит. Что я могу делать неправильно? Это SecurityConfig:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;
    private final AuthenticationProvider authProvider;
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
            .csrf(csrf->
                csrf.disable())
            .authorizeHttpRequests(authRequest ->
                authRequest
                    .requestMatchers("/auth/**").permitAll()
                    .anyRequest().authenticated()
            )
            .sessionManagement(sessionManager ->
                sessionManager.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authenticationProvider(authProvider)
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
    }
}

Я всегда получаю ответ 403 Forbidden в Postman.

Есть идеи, что может быть не так? Отлажено, но не могу найти проблему. Я что-то упустил (наверное, глупость), но не могу найти.
Заранее спасибо!

Обновлено: Это журналы с LogLevel DEBUG:

2024-07-01T11:50:08.830-07:00 DEBUG 15809 --- [WorkLogAPI] [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Securing POST /api/v1/demo/
Hibernate: select u1_0.id,u1_0.password,u1_0.role,u1_0.username from wluser u1_0 where u1_0.username=?
2024-07-01T11:50:33.405-07:00 DEBUG 15809 --- [WorkLogAPI] [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Secured POST /api/v1/demo/
2024-07-01T11:50:33.442-07:00 DEBUG 15809 --- [WorkLogAPI] [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : Securing POST /error
2024-07-01T11:50:33.443-07:00 DEBUG 15809 --- [WorkLogAPI] [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-07-01T11:50:33.444-07:00 DEBUG 15809 --- [WorkLogAPI] [nio-8080-exec-3] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access

Здравствуйте! Чтобы быть уверенным в отладчике, вы дошли до конца метода doFilterInternal и увидите, что для auth.isAuthenticated() установлено значение True? Вы также можете изменить безопасность Spring, чтобы получать больше журналов о цепочке фильтров, установив уровень журнала TRACE. Пример

Lansana Diomande 01.07.2024 19:36

журналы отладки показывают, что вы вызываете конечную точку без аутентификации — отсюда и значок 403. Вам нужно пройти метод doFilterInternal с отладчиком и посмотреть, почему не установлена ​​аутентификация

J Asgarov 01.07.2024 21:00

@JAsgarov, оценивающий SecurityContextHolder, передает принципалу правильные данные от пользователя и аутентификацию = true в конце doFilterInternal. SessionId имеет значение null, но должно ли оно быть нулевым?

daload 01.07.2024 21:11

sessionId имеет значение null, поскольку вы установили сеанс без сохранения состояния SessionCreationPolicy.STATELESS (нет сеанса). Но для аутентификации вам следует использовать какой-то заголовок/файл cookie токена jwt, а ваш jwtAuthenticationFilter должен установить объект аутентификации.

J Asgarov 01.07.2024 21:25

Токен передается в запрос правильно, поскольку я правильно получаю все данные из токена, и также выполняется SecurityContextHolder.getContext().setAuthentication(authTok‌​en), поскольку в конце doFilterInternal SecurityContextHolder.getContext(). getAuthentication().isAut‌​henticated() оценивается как true. Я не там ищу?

daload 01.07.2024 21:29

пожалуйста, удалите весь JWTFilter, раздача JWT браузерам опасна, и есть причина, по которой это не встроено в систему безопасности Spring. Пожалуйста, не просто гуглите и читайте блог, читайте настоящую документацию и не используйте JWT там, для чего они не предназначены. Прочтите документы.

Toerktumlare 02.07.2024 00:15

Этот вопрос похож на: Spring Boot 3 с исключениями Spring Security Intercepts. Я этого не хочу. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

dur 02.07.2024 08:52

Вы получаете 403, потому что ваша конечная точка /error не разрешена. Если вы откроете endpint, вы увидите настоящую причину.

dur 02.07.2024 08:54

@dur, спасибо, что указал на это, потому что это решило проблему. Я не знал, что это проблема с конечной точкой /error, поэтому не стал искать в этом направлении. Теперь мне интересно, почему отсутствие разрешения /error влияет на запрос, который не должен его выдавать.

daload 02.07.2024 10:11
2
9
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Благодаря @dur я решил эту проблему!

Моя конечная точка /error была защищена, поэтому был получен ответ 403. Добавление .requestMatchers("/error").permitAll() в мою безопасностьFilterChain решило проблему.

Приносим извинения всем, кто видел вопрос, похожий на Spring Boot 3 с исключениями Spring Security Intercepts, я этого не хочу Честно говоря, я не знал, что это проблема, поэтому не проводил никаких исследований в этом направлении. Спасибо всем, кто потратил время на помощь!!

Теперь мне интересно, почему это происходит. Думаю, сейчас я проведу небольшое исследование по этому поводу.

Другие вопросы по теме