Настройка CSRF для весеннего веб-сокета

Я создаю приложение, в котором аутентификация выполняется с помощью Spring Security для обработчиков HTTP, для HTTP я отключил защиту csrf, и теперь я хочу отключить csrf для весеннего веб-сокета, но я не могу понять, как это сделать, я уже пробовал много разных подходов, но, похоже, никто не работает. Если невозможно отключить csrf для WebSocket, как получить токен csrf? (Я попытался настроить конечную точку csrf для получения токена, но это не работает, и все руководства, которые я нашел, устарели) Заранее спасибо!

Конфигурация безопасности веб-сокета:

@Configuration
@EnableWebSocketSecurity
public class WebSocketSecurityConfig extends    AbstractSecurityWebSocketMessageBrokerConfigurer {
@Bean
AuthorizationManager<Message<?>> messageAuthorizationManager(
  MessageMatcherDelegatingAuthorizationManager.Builder messages)   {
messages.anyMessage().permitAll();

return messages.build();
}

@Override
    protected boolean sameOriginDisabled() {
    return true;
  }
}

Конфигурация безопасности:

@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfig {

  @Autowired
  private JwtFilter jwtFilter;

  @Bean
  SecurityFilterChain securityFilterChain(HttpSecurity HTTP)  throws Exception {
    return http.addFilterBefore(jwtFilter,   BasicAuthenticationFilter.class)
        .cors(AbstractHttpConfigurer::disable)
        .csrf(AbstractHttpConfigurer::disable)
        .authorizeHttpRequests(auth -> auth
        .requestMatchers("/authenticate").permitAll()
        .requestMatchers("/createchatroom").authenticated()
        .requestMatchers("/public/*").permitAll()
        .requestMatchers("/private/*").permitAll()
        .requestMatchers("/ws/**").authenticated()
        .requestMatchers("/register").permitAll()
        .requestMatchers("/csrf").authenticated()
         .requestMatchers("/addEmployeeToFavorites").hasAnyAuthority(EMPLOYEE.name(),
            ADMIN.name())
        .requestMatchers("/addChatRoomToFavorites")
        .hasAnyAuthority(EMPLOYEE.name(), ADMIN.name())
        .requestMatchers("/home").hasAnyAuthority(EMPLOYEE.name(), ADMIN.name()))
    .build();
  }
}

Может быть, вы можете показать текущую конфигурацию безопасности? Используете ли вы новейшую загрузочную систему Spring Boot 2.7 или что вы используете?

Yannick Mussche 10.01.2023 11:43

Да конечно есть версии пакетов: spring-boot-starter-security: 3.0.1 spring-boot-starter-websocket:3.0.1

Nikolaj 10.01.2023 11:52

Это не 2.7, .. вы уже где-то использовали " http.cors().and().csrf().disable() "? иначе я могу сформулировать ответ

Yannick Mussche 10.01.2023 12:00

Да, я использую его в конфигурации безопасности

Nikolaj 10.01.2023 12:04
Лучшая компания по разработке спортивных приложений
Лучшая компания по разработке спортивных приложений
Ищете лучшую компанию по разработке спортивных приложений? Этот список, несомненно, облегчит вашу работу!
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
Деревья поиска (Алгоритм4 Заметки к учебнику)
Деревья поиска (Алгоритм4 Заметки к учебнику)
(1) Двоичные деревья поиска: среднее lgN, наихудшее N для вставки и поиска.
0
4
121
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

По умолчанию Spring Security требует маркер CSRF в любом типе сообщения CONNECT. Это гарантирует, что только сайт, имеющий доступ к токену CSRF, сможет подключиться. Поскольку только один и тот же источник может получить доступ к токену CSRF, внешним доменам не разрешено устанавливать соединение.

Spring Security 4.0 представила поддержку авторизации для WebSockets через абстракцию Spring Messaging.

В Spring Security 5.8 эта поддержка была обновлена ​​для использования API AuthorizationManager.

Чтобы настроить авторизацию с помощью конфигурации Java, просто включите аннотацию @EnableWebSocketSecurity и опубликуйте AuthorizationManager<Message<?>> bean-компонент или в XML используйте атрибут use-authorization-manager. Один из способов сделать это — использовать AuthorizationManagerMessageMatcherRegistry для указания шаблонов конечных точек следующим образом:

@Configuration
@EnableWebSocketSecurity

public class WebSocketSecurityConfig {
@Bean
AuthorizationManager<Message<?>> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) {
    messages
            .simpDestMatchers("/user/**").authenticated()

    return messages.build();
    }
}
  1. Любому входящему сообщению CONNECT требуется действительный токен CSRF для обеспечения соблюдения Политики единого источника.
  2. SecurityContextHolder заполняется пользователем в атрибуте заголовка simpUser для любого входящего запроса.
  3. Наши сообщения требуют соответствующей авторизации. В частности, для любого входящего сообщения, начинающегося с «/user/», потребуется ROLE_USER. Дополнительную информацию об авторизации можно найти в [websocket-authorization]
На данный момент CSRF нельзя настроить при использовании @EnableWebSocketSecurity, хотя это, вероятно, будет добавлено в будущем выпуске.

Чтобы отключить CSRF, вместо использования @EnableWebSocketSecurity вы можете использовать поддержку XML или самостоятельно добавить компоненты Spring Security, например:

Джава

@Configuration
public class WebSocketSecurityConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        AuthorizationManager<Message<?>> myAuthorizationRules = AuthenticatedAuthorizationManager.authenticated();
        AuthorizationChannelInterceptor authz = new AuthorizationChannelInterceptor(myAuthorizationRules);
        AuthorizationEventPublisher publisher = new SpringAuthorizationEventPublisher(this.context);
        authz.setAuthorizationEventPublisher(publisher);
        registration.interceptors(new SecurityContextChannelInterceptor(), authz);
   }
}

Веб.xml

<websocket-message-broker use-authorization-manager = "true" same-origin-disabled = "true">
    <intercept-message pattern = "/**" access = "authenticated"/>
</websocket-message-broker>

С другой стороны, если вы используете legacy-websocket-configuration и хотите разрешить другим доменам доступ к вашему сайту, вы можете отключить защиту Spring Security. Например, в конфигурации Java вы можете использовать следующее:

@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

...

    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }
}

Рекомендации

Спасибо за ваш ответ! Могу я спросить вас, как я могу сгенерировать токен csrf?

Nikolaj 10.01.2023 12:07

Привет! Не беспокойся. Попробуйте поискать реализацию csrf в этом: youtube.com/watch?v=roVG7Qgm4hU С уважением

Rayyan Karimi 10.01.2023 13:15

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

Rayyan Karimi 10.01.2023 18:44

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