Миграция Spring Security на Spring Security 6

Меня очень смущают новые сопоставители Spring Security. Мой текущий код (SecurityConfiguration расширяет WebSecurityConfigurerAdapter):

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http.csrf().disable()
        .antMatcher("/some/endpoint")
        .addFilterBefore(new CustomFilter(), BasicAuthenticationFilter.class)
        .authorizeRequests()
            .anyRequest().permitAll()
            .and()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

Что будет эквивалентно SecurityConfiguration? Я зашел так далеко, но, похоже, это работает не так, как ожидалось:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
    return http.csrf(AbstractHttpConfigurer::disable)
               .authorizeHttpRequests(authz ->
                    authz.requestMatchers("/some/endpoint").permitAll()
                    .anyRequest().authenticated()
               )
               .addFilterBefore(new CustomFilter(), BasicAuthenticationFilter.class)
               .sessionManagement(sessionManagementConfigurer -> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
               .build();
}

Теперь я вижу, что большинство моих вызовов на открытие URL-адресов типа /actuator/health заблокированы.

Я также прочитал в руководстве по миграции:

В Spring Security 5.8 и более ранних версиях запросы без правила авторизации разрешены по умолчанию.

Каков наилучший подход?

Отвечает ли это на ваш вопрос? Защита конечных точек исполнительного механизма, кроме /health

dur 08.06.2024 20:43

Спасибо за ваше предложение. Это отличается. В качестве примера я привел здоровье, но у меня гораздо больше конечных точек. Фактически защищена только одна конечная точка, остальные открыты.

BarbetNL 10.06.2024 13:28

Тогда вам придется открыть и все остальные. Просто добавьте остальные. Ваш собственный ответ — плохая практика, вы не должны разрешать «любой запрос». Однако ваш старый код также является плохой практикой, не используйте antMatcher, если у вас только одна цепочка фильтров.

dur 10.06.2024 14:10
Пользовательский скаляр 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 .
2
3
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Мне нужно было переключиться, чтобы это заработало:

authz.requestMatchers("/some/endpoint").permitAll()
     .anyRequest().authenticated()

к

authz.requestMatchers("/some/endpoint").authenticated()
     .anyRequest().permitAll()

Более чистый способ (предложенный @KenS) — создать два компонента безопасности:

@Order(0)
@Bean
public SecurityFilterChain secureEndpoint(HttpSecurity httpSecurity) throws Exception {
    return httpSecurity.csrf(AbstractHttpConfigurer::disable)
            .securityMatcher("/secure-endpoints/**")
            .authorizeHttpRequests(authorize -> authorize
                    .anyRequest()
                    .authenticated()
            )
            .addFilterBefore(new CustomFilter(), BasicAuthenticationFilter.class)
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .build();
}

@Order(1)
@Bean
public SecurityFilterChain openEndpoints(HttpSecurity http) throws Exception {
    return http.csrf(AbstractHttpConfigurer::disable).securityMatcher("/open-endpoints/**")
            .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()
            )
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .build();
}

Хотя это не эквивалентно. Взгляните на SecurityMatcher как на замену antMatcher. См. примеры docs.spring.io/spring-security/reference/5.8/migration/servl‌​et/…. Если у вас есть только один bean-компонент SecurityFilterChain, ваше решение также должно работать.

Ken S 07.06.2024 17:30

У меня есть только один bean-компонент SecurityFilterChain. Я вижу, что это работает. Я хотел бы узнать, как это будет работать правильно (например, исходная настройка). Понадобятся ли мне 2 bean-компонента: один для защищенных и один для открытых конечных точек?

BarbetNL 10.06.2024 13:27

Я бы сделал именно так, но ваше решение подходит для вашего примера. У вас может быть текущий SecurityFilterChain с http.securityMatchers("/some/endpoint").authorizeHttpRequest‌​s(authz -> authz.anyRequest().authenticated()) и второй без SecurityMatchers и authz.anyRequest().permitAll(). Обязательно добавьте аннотации @Order(...) для обоих bean-компонентов, чтобы определить их порядок (меньшее число имеет приоритет). Для более сложных конфигураций см. docs.spring.io/spring-security/reference/servlet/configurati‌​on/… для начала.

Ken S 10.06.2024 14:22

Самое большое преимущество использования нескольких bean-компонентов SecurityFilterChain — это когда вам нужно иметь разные механизмы авторизации для разных точек входа. Вы можете защитить свою «/some/endpoint» с помощью CustomFilter, «/another/endpoint» с помощью oauth2, использовать базовую аутентификацию для привода и «denyAll» для всего остального.

Ken S 10.06.2024 14:28

@KenS Я обновил решение с учетом вашего предложения. Я попробовал, и это работает. Мне это нравится гораздо больше.

BarbetNL 11.06.2024 14:30

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

Как определить предоставленные пользователем полномочия на основе ролей пользователей в Auth0 с помощью Spring Boot
Как я могу пройти аутентификацию, используя тип гранта обмена токенами для олицетворения с помощью Spring Boot и Keycloak?
Какой алгоритм шифрования использует PasswordEncoder Spring Security?
Spring безопасность: как скрыть или обойти страницу «вход с помощью oauth2» с помощью одного клиента oauth при использовании oauth2Login
Как обойти страницу входа в систему keycloak и предоставить предложенному клиентом идентификатору Spring Security
Spring Security. Эта страница не работает. Localhost перенаправлял вас слишком много раз. при попытке доступа к localhost:8080 с помощью Spring Security
Почему мой пользователь анонимен после входа в систему по OAuth2 с помощью Spring Boot?
Ошибка происхождения Cors приложения микросервиса Spring Boot
Spring безопасность oauth2Login на основе средства сопоставления запросов
Пытается ли Spring Security авторизовать клиента для общедоступной конечной точки?