SpringBoot as WAR не загружает / не инициализирует Spring Config для Keycloak - PullRequest
1 голос
/ 17 июня 2020

У меня есть сборка приложения SpringBoot 2.3.1 с maven, которая загружает некоторую конфигурацию из application.yml в src/main/resources.

В качестве JAR конфигурация загружается из <jarfile>/BOOT-INF/classes/application.yml.

В качестве WAR конфигурация не загружается (ноль), но WAR содержит ее в <warfile>/WEB-INF/classes/application.yml

Мои соответствующие зависимости:

...
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
...

и профиль является выпуском.

  <profiles>
    <profile>
      <id>dev</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <project.packaging>jar</project.packaging>
      </properties>
    </profile>
    <profile>
      <id>release</id>
      <properties>
        <project.packaging>war</project.packaging>
      </properties>
      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          <exclusions>
            <exclusion>
              <artifactId>spring-boot-starter-tomcat</artifactId>
              <groupId>org.springframework.boot</groupId>
            </exclusion>
          </exclusions>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.0.1</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>
    </profile>
  </profiles>

  <build>
    <defaultGoal>spring-boot:run</defaultGoal>
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

Я тестировал это с помощью

/** Main Entry Point for this Application */
@SpringBootApplication
public class Application extends SpringBootServletInitializer implements WebApplicationInitializer {
  private static final Logger log = LoggerFactory.getLogger(Application.class);

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    log.info("Configure Servlet");
    return builder.sources(Application.class);
  }
}

И класс конфигурации, например :

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@KeycloakConfiguration
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
...
  @Value("${spring.application.name}")
  private String name;
  @Value("${keycloak.realm}")
  private String realm;

  /** Set Keycloak Config Resolver to use Spring Config */
  @Bean
  public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
    log.error("1-spring.application.name is: " + name);
    log.error("1-keycloak.realm is: " + realm);
    KeycloakSpringBootConfigResolver resolver = new KeycloakSpringBootConfigResolver();
    return resolver;
  }

  @Bean(name = "MyTEST1")
  String getString() {
    log.error("2-spring.application.name is: " + name);
    log.error("2-keycloak.realm is: " + realm);
    return "Hello world";
  }

В сообщении журнала во время запуска я вижу, что область и имя - null в методе keycloakConfigResolver(), но миллисекунды позже не равны нулю в getString(). Журналы 2- находятся сразу после журналов 1-.. в моем файле журнала.

2020-06-18 15:14:58.438 DEBUG 14536 --- [alina-utility-2] d.m.selfservices.platform.Application    : Running with Spring Boot v2.3.1.RELEASE, Spring v5.2.7.RELEASE
2020-06-18 15:14:58.440  INFO 14536 --- [alina-utility-2] d.m.selfservices.platform.Application    : No active profile set, falling back to default profiles: default
2020-06-18 15:14:59.711  INFO 14536 --- [alina-utility-2] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1233 ms
2020-06-18 15:15:00.192 ERROR 14536 --- [alina-utility-2] d.m.s.platform.SecurityConfig            : 1-spring.application.name is: null
2020-06-18 15:15:00.192 ERROR 14536 --- [alina-utility-2] d.m.s.platform.SecurityConfig            : 1-keycloak.realm is: null
2020-06-18 15:15:00.664  INFO 14536 --- [alina-utility-2] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@167c9b7e, org.springframework.security.web.context.SecurityContextPersistenceFilter@4c7dee5, org.springframework.security.web.header.HeaderWriterFilter@43d8836e, org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter@2d74b982, org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter@2d74b982, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter@1d951d12, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter@1d951d12, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@13256bad, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4f27b99b, org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter@2839e57e, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter@41fb5754, org.springframework.security.web.session.SessionManagementFilter@149db72c, org.springframework.security.web.access.ExceptionTranslationFilter@49d41456, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@2aa4e85a]
2020-06-18 15:15:00.683 ERROR 14536 --- [alina-utility-2] d.m.s.platform.SecurityConfig            : 2-spring.application.name is: Plattform
2020-06-18 15:15:00.683 ERROR 14536 --- [alina-utility-2] d.m.s.platform.SecurityConfig            : 2-keycloak.realm is: myrealm
2020-06-18 15:15:00.931  INFO 14536 --- [alina-utility-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-06-18 15:15:01.170  INFO 14536 --- [alina-utility-2] d.m.selfservices.platform.Application    : Started Application in 3.277 seconds (JVM running for 1431.91)

Я могу подтвердить это поведение на Tomcat 9.0.36, Wildfly 20 и с Spring Boot 2.2.6 и Keycloak 9.0 .3 и 10.0.2. Со встроенным Tomcat все нормально. Когда я намеренно ошибаюсь в написании keycloak.realm, я правильно получаю исключение, что значение не может быть разрешено.

Итак, свойства есть, я могу связаться с ними с помощью простого определения bean, но во время keycloakConfigResolver () это недоступно. Я знаю о «новом», но это пример из Keycloak.

Что я пропускаю?

1 Ответ

1 голос
/ 19 июня 2020

Я предполагаю, что проблема здесь в создании KeycloakSpringBootConfigResolver через «новый».

У распознавателя есть внутренний объект AdapterConfig. В рамках некоторого рефакторинга / исправления ошибок этот объект некоторое время стал не- static go. Перед изменением static AdapterConfig был установлен централизованно, и все экземпляры (созданные с помощью new) могли получить доступ к этому объекту. Так что, похоже, это ошибка в spring-keycloak.

Причина root здесь в том, что KeycloakSpringBootConfigResolver должен был быть создан самим Spring, а AdapterConfig должен был быть объявлен @Autowired поле (или задано с помощью конструктора).

На ум приходят два возможных решения.

  1. Создайте свой KeycloakSpringBootConfigResolver (на самом деле кода там мало), используя @Autowired на поле AdapterConfig (инъекция будет выполнена Spring после того, как ваш keycloakConfigResolver() аннотированный метод вернет экземпляр
  2. Установите AdapterConfig через отражение в вашем keycloakConfigResolver() методе
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...