Как отключить Spring (Boot) Security OAuth на основе профиля конфигурации или определенного свойства?

Я интегрирую OAuth2 (Google в качестве поставщика OIDC) в существующее приложение Spring Boot, которое в настоящее время использует простой DaoAuthenticationProvider. Я внес изменения, чтобы интеграция OAuth работала, но теперь мне нужно предоставить переключатель конфигурации, чтобы отключить ее в определенных средах (вернуться к использованию старой аутентификации на основе базы данных).

Конфигурация для использования OAuth2 выглядит следующим образом:

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: 1234567890-1a2b3c4d5e6f7g8h9i0j.apps.googleusercontent.com
            client-secret: ABCDEF-1234-OU812_XYZZY

Мой класс @Configuration для аутентификации выглядит так:

@Configuration
@EnableWebSecurity
public class GoogleOIDCSecurityConfiguration {

    @Bean
    OidcUserService oidcUserService() {
        Set<String> scopes = Set.of(
                "https://www.googleapis.com/auth/userinfo.email",
                "https://www.googleapis.com/auth/userinfo.profile"
                );
        OidcUserService service = new OidcUserService();
        service.setAccessibleScopes(scopes);
        return service;
    }

    @Bean
    SecurityFilterChain oidcFilterChain(HttpSecurity http, OidcUserService userService) throws Exception {
        http
            .authorizeHttpRequests(this::configureAuthorization)
            .oauth2Login(c -> configureOAuth2(c, userService))
            .logout(this::configureLogout)
            ;

        return http.build();
    }

    protected void configureAuthorization(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorize) {
        authorize
            .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR).permitAll()

            .requestMatchers("/*/*.js", "/*/*/*.js", "/css/**", "/lib/**", "/assets/**", "favicon.ico").permitAll()
            .requestMatchers("/", LOGIN_PAGE, INVALID_SESSION_PAGE, LOGOUT_PAGE).permitAll()
            .requestMatchers("/foo/**").hasAnyRole(Roles.FOO)
            .requestMatchers("/admin/**").hasRole(Roles.ADMIN)
            .anyRequest().authenticated();
    }

    private void configureOAuth2(OAuth2LoginConfigurer<HttpSecurity> oauthLogin, OidcUserService userService) {
        oauthLogin
            .userInfoEndpoint(endpoint -> endpoint.oidcUserService(userService));
    }
}

Моя первая попытка условно отключить его заключалась в том, чтобы установить client-id пустым в определенных профилях и использовать @ConditionalOnProperty для ссылки на этот ключ. Это не удается из-за исключения проверки, говорящего, что client-id не может быть пустым. Кажется, что наличие чего-либо под spring.security.oauth2.client.registration.* запускает автоматическую настройку OAuth.

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

Пользовательский скаляр 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
0
719
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Почему бы вам не поместить все свои свойства конфигурации и компоненты OAuth2 в этот профиль?

# properties for all profiles here

---
spring:
  config:
    activate:
      on-profile:
      - oauth2
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: 1234567890-1a2b3c4d5e6f7g8h9i0j.apps.googleusercontent.com
            client-secret: ABCDEF-1234-OU812_XYZZY
@Profile("oauth2")
@Configuration
@EnableWebSecurity
public class GoogleOIDCSecurityConfiguration {
    ...
}
@Profile("legacy")
@Configuration
@EnableWebSecurity
public class LegacySecurityConfiguration {
    ...
}

Вероятно, было бы более полезно добавить аналог Gradle.

ch4mp 03.04.2024 18:59

Обратите внимание, что вы можете «автоматически подписаться», установив этот профиль oauth2 активным по умолчанию. В Maven профиль activeByDefault отключается, если явно задан хотя бы другой профиль (поэтому вам также придется установить его явно, если вы хотите, чтобы он был связан с другим профилем). В Gradle может быть аналогичная функция. В вашем случае я бы установил профиль oauth2 активным по умолчанию, а также определил бы профиль legacy с deps и conf для более старой системы, чтобы у меня одновременно был только один из двух conf и deps.

ch4mp 03.04.2024 19:08

Мы используем «локальный» профиль во всех средах, чтобы можно было легко переопределить его с помощью application-local.yml (в ближайшее время это не изменится), поэтому я не думаю, что трюк с созданием oauth2 активного профиля по умолчанию сработает.

E-Riz 03.04.2024 19:21

Не путайте профили Maven (или Gradle) и Spring (local — это профиль Spring). Внимательно посмотрите на отредактированный ответ для ручной синхронизации между профилями Maven и Spring. Также обратите внимание, что каждый из этих профилей Maven можно использовать «локально»: oauth2 не активируя профиль Maven (или с явной активацией) и legacy только с явной активацией (отключив oauth2, если также не активировать явно, но зачем это делать?)

ch4mp 03.04.2024 19:27

Я удаляю часть ответа, касающуюся Maven, поскольку она не имеет прямого отношения к ответу на вопрос. Интересная информация, но я чувствую, что это сбивает с толку полезный ответ. Мне также принципиально не нравится необходимость сборки отдельно для разных сред. Создайте один раз, разверните много.

E-Riz 03.04.2024 19:39

Жаль, что я вас запутал, потому что, вероятно, было бы предпочтительнее, чтобы у вас одновременно был только один набор зависимостей от пути к классам (и это требует некоторой настройки системы сборки). Лучший способ отключить стартер Spring Boot — это удалить его из пути к классам: больше никаких транзитивных зависимостей и никакой автоматической настройки.

ch4mp 03.04.2024 20:04

Хороший улов на csrf.dissble() звонок. Это была ошибка копирования и вставки при написании нового класса конфигурации OAuth2. Я удалил его из кода в вопросе.

E-Riz 03.04.2024 20:20

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