ServerHttpSecurity authorizeExchange PermitAll не работает

Я настроил аутентификацию auth0 с помощью шлюза Spring Cloud API. Моя базовая настройка выглядит следующим образом:

  • POST — /пользователь/апи/пользователь/регистрация — Разрешить все

  • Все другие конечные точки API — аутентифицированный.

Поэтому использовал следующую SecurityConfiguration с приложением весенней загрузки,

package com.app.source.configuration.security;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
                .authorizeExchange()
                //ALLOW USER REGISTRATION API WITHOUT AUTHENTICATION
                .pathMatchers("/user/api/v1/user/registration").permitAll()
                //ALL OTHER APIS ARE AUTHENTICATED
                .anyExchange().authenticated()
                .and()
                .csrf().disable()
                .oauth2Login()
                .and()
                .oauth2ResourceServer()
                .jwt();
        return http.build();
    }
}

Уровень аутентификации применен к необходимым конечным точкам API, и он работает так, как мне нужно, но эта конечная точка регистрации отправляет пустой ответ 200, но не проходит через шлюз API. Но тот же API работает при отправке с заголовком аутентификации. Я прилагаю журналы DEBUG, которые у меня есть с шлюзом API.

API, который должен иметь токен аутентификации, который работает правильно и отправляет 401 при неавторизованных запросах.

ServerHttpSecurity authorizeExchange PermitAll не работает

API, который был настроен открытым, который отправляет 200 из шлюза API без прохождения,

ServerHttpSecurity authorizeExchange PermitAll не работает

Тот же API хорошо работает, когда я прикрепляю токен авторизации, что неприемлемо.

ServerHttpSecurity authorizeExchange PermitAll не работает

Request with valid auth token

2022-05-14 02:26:29.918 DEBUG 9999 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-10, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] HTTP POST "/user/api/v1/user/registration"
2022-05-14 02:26:29.934 DEBUG 9999 --- [oundedElastic-3]
o.s.w.s.s.DefaultWebSessionManager       : Created new WebSession.
2022-05-14 02:26:32.497 DEBUG 9999 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-10, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] Completed 200 OK


-----------

Request without token which is returning 200 in the same second without processing it.

2022-05-14 02:26:45.950 DEBUG 9999 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-11, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] HTTP POST "/user/api/v1/user/registration"
2022-05-14 02:26:45.960 DEBUG 9999 --- [oundedElastic-3] o.s.w.s.s.DefaultWebSessionManager       : Created new WebSession.
2022-05-14 02:26:45.977 DEBUG 9999 --- [oundedElastic-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-11, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] Completed 200 OK

Просто любопытно, защищенная конечная точка /user/api/v1/user/registration отличается от той, что на изображениях, /api/v1/user/registration. Конфигурация цепочки фильтров находится в шлюзе или службе? А скриншоты бьют шлюз или сервис?

jzheaux 13.05.2022 23:40

@Chinthaka Dinadasa У вас есть какой-нибудь класс, который делает implement AuthenticationEntryPoint. Если да, напишите об этом в вопросе

Panagiotis Bougioukos 13.05.2022 23:44

У меня точно такая же проблема

Juan Rosales Vargas 14.05.2022 06:41

Я думаю, что код из github.com/javatodev/интернет-банкинг-концепт-микросервисы

Juan Rosales Vargas 14.05.2022 06:45

Привет, @jzheaux {{user_service}} = {{api_gateway_host}}/user. Итак, я установил эту переменную от почтальона. В основном последний запрос направляется на шлюз API.

Chinthaka Dinadasa 14.05.2022 10:02

@PanagiotisBougioukos В данный момент я ничего не добавлял. Дай мне попробовать

Chinthaka Dinadasa 14.05.2022 10:03

@JuanRosalesVargas Эй, да, это было место, о котором я упоминал

Chinthaka Dinadasa 14.05.2022 10:03
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
7
24
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

проблема в фильтре

 @Bean
public GlobalFilter customGlobalFilter() {

    return ((exchange, chain) -> exchange.getPrincipal().map(principal -> {
        String userName = "";

        if (principal instanceof JwtAuthenticationToken) {
            //Get username from Principal
            userName = principal.getName();
        }
        // adds header to proxied request
        exchange.getRequest().mutate()
                .header("X-Auth-Id", userName)
                .build();
        return exchange;
    }).flatMap(chain::filter).then(Mono.fromRunnable(() -> {

    })));
}

если удалить работает нормально

Привет, @juan, да, ты прав. Это произошло с этим фильтром, изменил фильтр следующим образом и работает нормально.

Chinthaka Dinadasa 14.05.2022 11:22

Исходная проблема была связана с настраиваемым фильтром, который был написан для захвата основного имени пользователя входящего запроса, добавленного defaultIfEmpty и разрешенного несанкционированного запроса пользователя.

package com.app.configuration;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

import java.security.Principal;

@Slf4j
@Configuration
public class GatewayConfiguration {

    private static final String HTTP_HEADER_AUTH_USER_ID = "X-Auth-Id";
    private static final String UNAUTHORIZED_USER_NAME = "SYSTEM USER";

    @Bean
    public GlobalFilter customGlobalFilter() {
        return (exchange, chain) -> exchange.getPrincipal().map(Principal::getName).defaultIfEmpty(UNAUTHORIZED_USER_NAME).map(principal -> {
            // adds header to proxied request
            exchange.getRequest().mutate()
                    .header(HTTP_HEADER_AUTH_USER_ID, principal)
                    .build();
            return exchange;
        }).flatMap(chain::filter).then(Mono.fromRunnable(() -> {

        }));
    }

}

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