Как защитить конечную точку веб-сокета микросервиса с помощью Spring Cloud Gateway?

У меня есть проект на основе микросервисной архитектуры, для которого я добавил Spring Cloud Gateway впереди. Мой план — централизовать безопасность на шлюзе. Я добавил OIDC и OAuth 2 для аутентификации и авторизации, которые работают как положено. Шлюз играет роль клиента OAuth и сервера ресурсов. Он использует поток кода авторизации. Я использовал фильтр TokenRelay для передачи информации нижестоящим службам. Я также включил CORS и CSRF (включен по умолчанию) в шлюзе.

Проблема, с которой я столкнулся, больше связана с CSRF, чем с чем-либо еще. Для обычных HTTP-вызовов все работает нормально, поскольку нижестоящая служба проверяет заголовок авторизации (который добавляется через TokenRelay) и, похоже, пропускает проверку CSRF, по сути доверяя шлюзу. Я хотел бы того же самого для соединений через веб-сокеты. В настоящее время, если я включу безопасность веб-сокета (через @EnableWebsocketSecurity), он включит проверку CSRF, но отправка токена шлюза вызовет исключение, поскольку он ожидает токен нижестоящей службы (у него есть собственный репозиторий токенов). Если я отключу безопасность веб-сокетов (и неявно CSRF), отправка/отправка токена шлюза не имеет никакого значения.

Есть ли способ добиться такого же поведения от HTTP-вызовов в веб-сокетах со шлюзом? Я знаю, что одним из вариантов было бы создать своего рода централизованное хранилище токенов и использовать его как в шлюзе, так и в микросервисе, но это кажется хлопотным.

Мое текущее решение — отключить CSRF для микросервиса, так как я не уверен, как токен CSRF помогает в случае веб-сокетов, поскольку Spring Security/Spring Websockets реализует проверку заголовка Origin на стороне сервера (политика одного и того же происхождения на стороне сервера), которая, похоже, быть достаточным. Об этом я уже писала здесь.

ПОЗЖЕ РЕДАКТИРОВАТЬ

Для HTTP-запросов CsrfFilter будет обходить проверку токена csrf, если присутствует токен носителя. Это связано с тем, что микросервис является сервером ресурсов oauth (см. объяснение в OAuth2ResourceServerConfigurer.registerDefaultCsrfOverride ). Однако этого не происходит для веб-сокетов. Это задумано или это баг?

Ниже приведен код:

Нижестоящий сервис

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@EnableWebSocketSecurity
public class DownstreamServiceSecurityConfiguration {


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
                .csrf(csrfSpec -> csrfSpec.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
                .oauth2ResourceServer((oauth2) -> oauth2.jwt(withDefaults()));
        return http.build();
    }

.....

шлюз

@Configuration
@EnableWebFluxSecurity
public class GatewaySecurityConfiguration {

    @Autowired
    public SecurityConfiguration(ReactiveClientRegistrationRepository clientRegistrationRepository) {
        this.clientRegistrationRepository = clientRegistrationRepository;
    }

    ReactiveClientRegistrationRepository clientRegistrationRepository;

    private ServerLogoutSuccessHandler serverLogoutSuccessHandler() {
        OidcClientInitiatedServerLogoutSuccessHandler successHandler = new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository);
        //needs to match the one declared at auth-server
        successHandler.setPostLogoutRedirectUri("{baseUrl}/api-docs");
        return successHandler;
    }

    @Bean
    public SecurityWebFilterChain filterChain(ServerHttpSecurity http){

        http.cors(withDefaults())
                // add csrf token that can be handled by js clients by using CookieServerCsrfTokenRepository.withHttpOnlyFalse()
                .csrf(csrfSpec -> csrfSpec.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
                        .csrfTokenRequestHandler(new SpaServerCsrfTokenRequestHandler()))
                .authorizeExchange(authorizeExchangeSpec -> authorizeExchangeSpec.pathMatchers("/api-docs/**", "/swagger-ui.html", "/webjars/swagger-ui/**", "/actuator/**", "/oidc/**").permitAll()
                        .pathMatchers("/notification/ws-connect").hasAuthority("SCOPE_customer-read")
                        .anyExchange().authenticated())
                //handle oidc authentication by redirecting to auth server login page
                .oauth2Login(withDefaults())
                //make gateway also a resource server that supports jwt bearer token, as the default configuration does not kick in because we also have the client dependency on the classpath
                .oauth2ResourceServer(oAuth2ResourceServerSpec -> oAuth2ResourceServerSpec.jwt(withDefaults()))
                .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutSuccessHandler(serverLogoutSuccessHandler()));
        return http.build();
    }

    //When storing the expected CSRF token in a cookie, JavaScript applications will only have access to the plain token value and will not have access to the encoded value.
    //A customized request handler for resolving the actual token value will need to be provided.
    //See https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#csrf-integration-javascript-spa
    static final class SpaServerCsrfTokenRequestHandler extends ServerCsrfTokenRequestAttributeHandler {
        private final ServerCsrfTokenRequestAttributeHandler delegate = new XorServerCsrfTokenRequestAttributeHandler();

        @Override
        public void handle(ServerWebExchange exchange, Mono<CsrfToken> csrfToken) {
             // Always use XorCsrfTokenRequestAttributeHandler to provide BREACH protection of the CsrfToken when it is rendered in the response body.
            this.delegate.handle(exchange, csrfToken);
        }

        @Override
        public Mono<String> resolveCsrfTokenValue(ServerWebExchange exchange, CsrfToken csrfToken) {
            final var hasHeader = exchange.getRequest().getHeaders().get(csrfToken.getHeaderName()) !=null;
            return hasHeader ? super.resolveCsrfTokenValue(exchange, csrfToken) : this.delegate.resolveCsrfTokenValue(exchange, csrfToken);
        }
    }

    @Bean
    //Needed in order to set the XSRF-TOKEN cookie
    //See https://docs.spring.io/spring-security/reference/reactive/integrations/cors.html
   public WebFilter csrfCookieWebFilter() {
        return (exchange, chain) -> {
            exchange.getAttributeOrDefault(CsrfToken.class.getName(), Mono.empty()).subscribe(o -> ((CsrfToken)o).getToken());
            return chain.filter(exchange);
        };
    }


    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("http://localhost:63342"));
        configuration.setAllowedMethods(List.of(CorsConfiguration.ALL));
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(List.of(CorsConfiguration.ALL));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

Клиент

const stompClient = new StompJs.Client({
            brokerURL: 'ws://localhost:9990/notification/ws-connect',
            connectHeaders : {"X-XSRF-TOKEN":csrfToken}
        });

Ошибка при передаче токена, сгенерированного шлюзом

org.springframework.security.web.csrf.InvalidCsrfTokenException: Invalid CSRF Token 'd1f38e4e-71cc-4241-8c7e-3b01c1937c7c' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'

Я загрузил диаграмму, возможно, это лучше объясняет ситуацию:

Заранее спасибо ! Любая помощь приветствуется!

Пробовали ли вы настроить CSRF одинаково (для SPA) как на шлюзе, так и на нисходящей службе? Кроме того, почему вы считаете, что вам нужна защита CSRF в нисходящем сервисе?

Steve Riesenberg 28.06.2024 16:11

Мое намерение — централизовать безопасность на шлюзе. Однако шлюз не обеспечивает защиту CSRF для веб-сокетов, в то время как нижестоящая служба обеспечивает ее при использовании @EnableWebSocketSecurity. Вот почему я попытался использовать csrf в сервисе. Я думаю, что существует несоответствие между тем, как Spring Gateway обеспечивает безопасность веб-сокетов, и тем, как Spring Web это делает, поэтому я создал ошибку. Также теоретически, если вы предоставляете нижестоящей службе какой-либо пользовательский интерфейс бэк-офиса, который вызывает службу напрямую, у вас может возникнуть проблема с безопасностью, если csrf не включен.

IonutB 28.06.2024 19:24

На мой взгляд, лучшее поведение CSRF — это то, которое происходит при обычных http-вызовах. Шлюз сначала проверяет наличие токена csrf и, если он действителен, отправляет запрос нижестоящей службе. Нижестоящая служба проверяет наличие токена-носителя и, если он найден, пропускает проверку токена csrf, в противном случае выполняется проверка csrf. Такого поведения не происходит для веб-сокетов, и я не понимаю, почему это отличается.

IonutB 28.06.2024 19:29

Я уже объяснял, что безопасность веб-сокетов не зависит от безопасности HTTP-запросов. Вот почему они разные. Кажется, вы на самом деле собираетесь спросить, почему платформа не предназначена для автоматического распространения конфигурации из HTTP-запросов в веб-сокеты. Если это то, что вы спрашиваете?

Steve Riesenberg 28.06.2024 21:44

@SteveRiesenberg Думаю, у меня на самом деле есть 2 вопроса: 1) Как мы можем добавить защиту csrf для конечных точек веб-сокетов в шлюзе 2) почему веб-сокеты не подвержены такому же поведению, как HTTP-вызовы (пропустите проверку csrf, если присутствует токен носителя) - это была ошибка, которую я добавил на github. Также я думаю, что нашел причину, по которой CsrfTokenRepository не работает. Смотрите мой последний комментарий из ответа Дж. Аскерова.

IonutB 28.06.2024 22:05

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

Steve Riesenberg 01.07.2024 17:01

@SteveRiesenberg Я добавил POC в github.com/ionutbarau/demo-stackoverflow. Пожалуйста, дайте мне знать, если вам нужна более подробная информация

IonutB 06.07.2024 14:49
Пользовательский скаляр 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 .
0
7
200
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете определить использование CookieServerCsrfTokenRepository, что означает, что токены CSRF не будут сохраняться на сервере, а будут сохраняться только в файлах cookie:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
    .csrf(csrf -> csrf.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()))
    .build();
}

Затем интерфейс должен прочитать значение из файла cookie (XSRF-TOKEN) и отправить его с заголовком X-XSRF-TOKEN. Это решит вашу проблему. Серверная часть сравнит оба и разрешит запрос, если оба присутствуют и имеют совпадающие значения.

См. Использование CookieCsrfTokenRepository.

Спасибо за ответ. К сожалению, это не решает проблему. Я уже использовал CookieServerCsrfTokenRepository. Возможно, я неправильно описал проблему. Если я включу CSRF в нисходящей службе для веб-сокетов (через @EnableWebSocketSecurity), он запросит токен, но тот, что от шлюза, бесполезен, поскольку он проверяет токен шлюза на соответствие нижестоящий репозиторий токенов службы и, конечно же, выдает исключение недопустимого токена. CookieServerCsrfTokenRepository помогает разрешить прием запроса шлюзом, но не веб-сокетами нижестоящих служб.

IonutB 26.06.2024 16:41

@IonutB Вы передаете как файл cookie (например, XSRF-TOKEN), так и заголовок (например, X-XSRF-TOKEN) нижестоящей службе, а также настраиваете нижестоящую службу для использования CsrfTokenRepository на основе файлов cookie? Вы не предоставили общий код, поэтому сложно узнать, как выглядит ваша конфигурация для каждого приложения.

Steve Riesenberg 28.06.2024 00:49

@Steve Изначально у меня не было CsrfTokenRepository в нисходящей службе, только на шлюзе. Я добавил его, и поведение такое же. Я отправляю и заголовок, и файл cookie, но токен генерируется шлюзом, поэтому, конечно, он попытается найти его в репозитории нижестоящей службы, следовательно, InvalidCsrfTokenException. При той же настройке, если я делаю вызов REST, все работает как положено, потому что CsrfFilter проверяет токен носителя и пропускает проверку токена CSRF. Я ожидал эту логику и для вызовов веб-сокетов, поэтому создал ошибку. Сегодня я постараюсь опубликовать здесь код.

IonutB 28.06.2024 08:17

с CookieServerCsrfTokenRepository он не пытается найти его в памяти, а только проверяет, совпадают ли значения cookie и заголовка (без сохранения состояния). Так что, если бы вы установили и то, и другое, у вас не должно возникнуть проблем.

J Asgarov 28.06.2024 08:31

Для http-вызовов он даже не пытается сопоставить, он просто пропускает проверку CSRF, регистрируя: «Не защищено от CSRF, поскольку запрос не соответствует И [CsrfNotRequired [TRACE, HEAD, GET, OPTIONS], Not [Или [org.springframework] .security.config.annotation.web.configur‌​ers.oauth2.server.re‌​source.OAuth2Resourc‌​eServerConfigurer$Be‌​arerTokenRequestMatc‌​her@1f05d08c]]]".

IonutB 28.06.2024 09:02

Я обновил вопрос с примером кода

IonutB 28.06.2024 09:03

Я полагаю, что файл cookie XSRF отправляется без моего вмешательства. Браузер отправит его, верно?

IonutB 28.06.2024 09:06

файлы cookie всегда отправляются автоматически браузером при условии, что настройка ДОМЕН в файле cookie точно соответствует домену, к которому делается запрос.

J Asgarov 28.06.2024 13:00

Я добавил диаграмму, возможно, это лучше объясняет ситуацию..

IonutB 28.06.2024 14:48

@JAsgarov, причина, по которой файлы cookie и заголовок не совпадают, связана с XorCsrfChannelInterceptor. В методе preSend() вызывается XorCsrfTokenUtils.getTokenValue(actualToken, ожидаемыйToken.getToken()). Это ошибочно вернет ноль, даже если два значения идентичны. Обходной путь — переключиться на CsrfChannelInterceptor, но это ошибка, которую необходимо исправить.

IonutB 28.06.2024 21:47
Ответ принят как подходящий

Спасибо за предоставленный образец. Это проясняет некоторые вещи, но есть несколько аспектов вашей настройки, которые требуют обратной связи и обсуждения.

Во-первых, я не вижу в вашем примере использования токенов-носителей для отправки запросов к шлюзу, поэтому вы можете удалить конфигурацию http.oauth2ResourceServer() в шлюзе.

Поскольку вы не используете токены-носители для запросов от клиента (я предполагаю, что это будет одностраничное приложение?) к шлюзу, для запросов HTTP POST требуется защита CSRF. CSRF-защита в данном случае находится между клиентом и шлюзом и не имеет ничего общего с notification-service.

Во-вторых, запрос на подключение представляет собой HTTP GET и не требует и не поддерживает защиту CSRF. Однако последующее рукопожатие веб-сокета происходит между клиентом и notification-service, при этом шлюз только пересылает запрос. Конфигурация шлюза в отношении CSRF никоим образом не влияет на это автоматически. Это странная установка, поскольку вы размещаете сервер веб-сокетов на сервере ресурсов и, следовательно, требуете, чтобы ваш клиент имел некоторые знания о том, как работает ваш бэкэнд (за шлюзом). Если вам действительно нужно это сделать, вы можете сделать это прозрачным, сопоставив конфигурацию CSRF между шлюзом (для HTTP-запросов) и notification-service (для сообщений веб-сокета), что вы и сделали. Поскольку эта настройка охватывает две системы, ничто не будет автоматически соответствовать конфигурации.

Не уверен, что это было задумано, но это сбивает с толку. Для http-вызовов Spring пропустит проверку CSRF, если обнаружен токен Bearer, а для веб-сокетов - нет, даже если начальное сообщение о подключении является http-вызовом.

Как я уже упоминал, настройка HTTP-запросов к серверу ресурсов (например, GET /ws-connect) так, чтобы они требовали только токена-носителя, никоим образом не влияет на сообщения веб-сокета. Это не ошибка. Оба имеют отдельную конфигурацию в Spring Security.

Файл cookie и заголовок CSRF не совпадают с конечной точкой подключения веб-сокетов. Эта проблема была решена с помощью CsrfChannelInterceptor.

Вы настроили веб-сокеты с защитой csrf на сервере ресурсов для использования CsrfChannelInterceptor (вместо XorCsrfChannelInterceptor), что эффективно соответствует конфигурации, которую вы используете на шлюзе, с SpaServerCsrfTokenRequestHandler. Это правильно и необходимо, поскольку ваш SPA-клиент отправляет простые токены CSRF вместо токенов BREACH (см. CsrfTokenRequestAttributeHandler и XorCsrfTokenRequestAttributeHandler).

Вопрос о stackoverflow: «Как защитить конечную точку веб-сокета микросервиса с помощью Spring Cloud Gateway?». Более конкретно, как реализовать csrf для конечной точки подключения веб-сокета в шлюзе. Я не нашел способа сделать это. Этот пример работает, поскольку я добавил csrf для веб-сокетов в нижестоящую службу, но это не то, что мне нужно.

Запрос на подключение через веб-сокет предназначен для notification-service, а не для шлюза. Мне непонятно, почему вы ожидаете здесь чего-то другого. В любом случае вы не можете отключить защиту CSRF на шлюзе или сервере веб-сокетов, поскольку запросы поступают из браузера. Поскольку вы только проксируете запросы и сообщения, шлюз не может улучшить ситуацию для вас.

В целом ваша конфигурация кажется мне в целом правильной. Однако это расширенная настройка. Потенциально мы могли бы улучшить документацию (это всегда хороший вариант), но эта настройка довольно специфична, поэтому я не уверен, как это будет выглядеть.

большое спасибо за ответ. Я добавил ответ, так как очень хотелось комментария

IonutB 08.07.2024 14:46

Вы сказали: «Поскольку вы только проксируете запросы и сообщения, шлюз не может улучшить ситуацию для вас». Это означает, что если бы я реализовал веб-сокеты на уровне шлюза, которые, в свою очередь, вызывают службу уведомлений, решит ли это мою проблему?

IonutB 09.07.2024 08:45

@SteveRisenBerg, извини, не знал, как с тобой связаться. У меня проблема Spring Security. Интересно, сможете ли вы вообще помочь: stackoverflow.com/questions/78747321/…

Sachin 15.07.2024 10:15

Я считаю, что для того, чтобы понять мои ответы, вам необходимо понять архитектуру, которую я пытаюсь достичь, поскольку это, конечно, повлияет на то, как я думаю и что я ожидаю (ошибочно или нет) от самой структуры. Мое намерение состоит в том, чтобы иметь несколько микросервисов, доступ к которым осуществляется через шлюз. Насколько мне известно, одна из вещей, которые вы реализуете в шлюзе, — это безопасность. CSRF является частью безопасности, поэтому его следует реализовать и в шлюзе. Насколько мне известно, существует практика централизации безопасности на шлюзе, чтобы охранять единственную дверь. Я ожидаю, что смогу защитить любую конечную точку, независимо от того, http это или веб-сокет. Основываясь на этом обосновании, вот мои ответы:

Во-первых, я не вижу в вашем образце использования токенов-носителей для отправки запросов к шлюзу, поэтому вы можете удалить конфигурацию http.oauth2ResourceServer() в шлюзе.

Пожалуйста, игнорируйте, поскольку у меня будет SPA со шлюзом в качестве клиента OAuth. Надеюсь, использование шлюза в качестве сервера ресурсов не является основной причиной моей проблемы. Я удалю его и посмотрю, что будет.

Поскольку вы не используете токены-носители для запросов от клиента (я предполагаю, что это будет одностраничное приложение?) к шлюзу, для запросов HTTP POST требуется защита CSRF. CSRF-защита в этом случае осуществляется между клиентом и шлюзом и не имеет ничего общего со службой уведомлений.

Я понимаю, что CSRF требуется для запросов POST, но поскольку служба уведомлений использует Spring-WebSockets, для которой требуется токен CSRF для конечной точки веб-сокета (https://docs.spring.io/spring-security/reference/servlet/integrations /websocket.html#websocket-sameorigin-csrf), разве шлюз не должен знать об этом и участвовать в этом?

Как я уже упоминал, настройка HTTP-запросов к серверу ресурсов (например, GET/ws-connect) так, чтобы требовался только токен носителя, никоим образом не влияет на сообщения веб-сокета. Это не ошибка. Оба имеют отдельную конфигурацию в Spring Security.

Не уверен, что я это понимаю, поскольку Spring-Security по умолчанию проверяет, существует ли токен на предъявителя, и если он найден, он пропускает проверку токена csrf, поскольку считает, что не может быть атаки csrf, если у вас есть токен вместо сеансовый файл cookie. ИМХО, это должно быть справедливо и для веб-сокетов, поскольку атака csrf происходит так же, как и http. Проверьте это, чтобы получить объяснение поведения токена-носителя-csrf для http

Вы настроили веб-сокеты с защитой csrf на сервере ресурсов для использования CsrfChannelInterceptor (вместо XorCsrfChannelInterceptor), который эффективно соответствует конфигурации, которую вы используете на шлюзе с SpaServerCsrfTokenRequestHandler. Это правильно и необходимо, поскольку ваш SPA-клиент отправляет простые токены CSRF вместо токенов BREACH (см. CsrfTokenRequestAttributeHandler и XorCsrfTokenRequestAttributeHandler).

Не уверен, что я делаю здесь неправильно. SpaServerCsrfTokenRequestHandler использует XorCsrfTokenRequestAttributeHandler в качестве делегата. По умолчанию XorCsrfChannelInterceptor используется на стороне сервера уведомлений. Разве XorCsrfTokenRequestAttributeHandler не должен работать с XorCsrfChannelInterceptor? Во время отладки я увидел две одинаковые строки, не равные...

Запрос на подключение через веб-сокет предназначен для службы уведомлений, а не для шлюза. Мне непонятно, почему вы ожидаете здесь чего-то другого.

По моему мнению, запрос на подключение через веб-сокет предназначен для шлюза, поскольку SPA не знает ни о какой службе уведомлений и не должен знать. Вся суть шлюза заключается в том, чтобы быть точкой входа в систему и обеспечивать маршрутизацию, размыкание цепей и безопасность, и это лишь некоторые из них. Таким образом, шлюз должен получить запрос, применить безопасность (проверить токен csrf и т. д.) и направить его в службу уведомлений, если запрос пройдет проверку безопасности.

В целом ваша конфигурация кажется мне в целом правильной. Однако это расширенная настройка. Потенциально мы могли бы улучшить документацию (это всегда хороший вариант), но эта настройка довольно специфична, поэтому я не уверен, как это будет выглядеть.

Я не уверен, почему это расширенная/специфическая настройка, поскольку, ИМХО, безопасность в шлюзе вполне стандартна. Из-за ситуации с веб-сокетами я вынужден разбросать конфигурацию безопасности по службам и шлюзу, что не кажется хорошим решением. Шлюз должен иметь возможность защищать все типы конечных точек, независимо от типа конечной точки (http, веб-сокеты или что-то еще).

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

Дополнительная логика проверки при обновлении токена доступа
Обработка внутренней ошибки сервера, когда эмитент OAuth недоступен в WebFluxSecurity
Почему защита CSRF необходима для подключения к веб-сокетам, если Spring Security реализует политику одинакового происхождения на уровне сервера?
Spring Security + Keycloak (с самоподписанными сертификатами) – как отключить проверку имени хоста?
Ошибка конфигурации безопасности при обновлении версии приложения весенней загрузки с 2.x.x до 3.3.0
Доступ запрещен даже при использовании AnonymousAuthenticationFilter
Spring безопасность 6 - авторизация не работает
Spring Boot 2.5.6 без Spring Security и конфигурации безопасности, обновленной до Spring Boot 3, из-за чего swagger не работает
Какова связь между временем простоя сеанса единого входа Keycloak и временем ожидания сеанса Spring?
Почему нам нужно загружать данные пользователя из БД для каждого запроса при аутентификации JWT с помощью Spring Security?