无法从配置服务器加载配置 - 没有合适的 HttpMessageConverter

问题描述 投票:0回答:1

我可以通过 http://localhost:8888 访问我的配置服务器,但无法从 location-service.yml 文件加载所需的配置。

我的配置服务器(CNF-S)

application.yml:

# Basic Configuration - Spring Config Server (CNF-S)
spring:
    application:
        name: Configuration
    profiles:
      active:
        - ${ENVIRONMENT} # Which is "dev" currently
      default: dev

# GitHub Repository (private & SSH)
    cloud:
      config:
        server:
          git:
            uri: [email protected]:*****/EMP_CNF-S.git # Private git repo
            ignore-local-ssh-settings: true
            default-label: ${ENVIRONMENT}
            private-key: ${GIT_SSH_KEY}
            search-paths: src/main/resources
            skip-ssl-validation: true
            timeout: 10
            clone-on-start: true

  # Spring Security
    security:
      user:
        name: ${EMP_CONFIG_USERNAME}
        password: ${EMP_CONFIG_PASSWORD}

# Server port
server:
  port: 8888
配置服务器 (CNF-S) 上的

location-service.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/location_db
    username: root
    password: test-123!

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

  test:
    database:
      replace: none

我的客户 - 定位服务 (LOC-S)

bootstrap.yml:

# Basic configs - Name & Profile
spring:
  application:
    name: location-service
  profiles:
    active:
      - ${ENVIRONMENT}

# Connecting to CNF-S - Configuration Server
  config:
    import: optional:configserver:${BASE_URL}:8888
  cloud:
    config:
      label: ${ENVIRONMENT}
      uri: ${BASE_URL}:8888
      name: location-service
      username: ${EMP_CONFIG_USERNAME}
      password: ${EMP_CONFIG_PASSWORD}

# Configuring Port for Location-Service
server:
  port: 8080

# Spring Actuator
management:
  endpoints:
    web:
      exposure:
        include:
          - health
          - info
      base-path: /actuator
  endpoint:
    health:
      show-details: always

问题描述

我可以登录我的配置服务器并在 http://localhost:8888/location-service/dev 上查看我的配置。但是,当我的客户尝试获取配置时,我收到以下错误:

2024-09-23T15:38:53.706+02:00  INFO 43435 --- [location-service] [  restartedMain] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8888
2024-09-23T15:38:53.712+02:00  WARN 43435 --- [location-service] [  restartedMain] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.cloud.config.environment.Environment] and content type [text/html;charset=UTF-8]
2024-09-23T15:38:53.714+02:00  INFO 43435 --- [location-service] [  restartedMain] com.emp.loc.LocationApplication          : The following 1 profile is active: "dev"
2024-09-23T15:38:53.719+02:00  INFO 43435 --- [location-service] [  restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader   : Fetching config from server at : http://localhost:8888
2024-09-23T15:38:53.719+02:00  WARN 43435 --- [location-service] [  restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader   : Could not locate PropertySource ([ConfigServerConfigDataResource@265110bb uris = array<String>['http://localhost:8888'], optional = true, profiles = 'default']): Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.cloud.config.environment.Environment] and content type [text/html;charset=UTF-8]
2024-09-23T15:38:53.719+02:00  INFO 43435 --- [location-service] [  restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader   : Fetching config from server at : http://localhost:8888
2024-09-23T15:38:53.719+02:00  WARN 43435 --- [location-service] [  restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader   : Could not locate PropertySource ([ConfigServerConfigDataResource@3373a584 uris = array<String>['http://localhost:8888'], optional = true, profiles = 'dev']): Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.cloud.config.environment.Environment] and content type [text/html;charset=UTF-8]
2024-09-23T15:38:53.719+02:00  INFO 43435 --- [location-service] [  restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader   : Fetching config from server at : http://localhost:8888
2024-09-23T15:38:53.719+02:00  WARN 43435 --- [location-service] [  restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader   : Could not locate PropertySource ([ConfigServerConfigDataResource@1d09bf99 uris = array<String>['http://localhost:8888'], optional = true, profiles = 'default']): Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.cloud.config.environment.Environment] and content type [text/html;charset=UTF-8]
2024-09-23T15:38:54.010+02:00  INFO 43435 --- [location-service] [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-09-23T15:38:54.016+02:00  INFO 43435 --- [location-service] [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 JPA repository interfaces.
2024-09-23T15:38:54.077+02:00  INFO 43435 --- [location-service] [  restartedMain] o.s.cloud.context.scope.GenericScope     : BeanFactory id=845d36ed-6367-395b-a199-708537ceebfe
2024-09-23T15:38:54.392+02:00  INFO 43435 --- [location-service] [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2024-09-23T15:38:54.400+02:00  INFO 43435 --- [location-service] [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-09-23T15:38:54.400+02:00  INFO 43435 --- [location-service] [  restartedMain] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.28]
2024-09-23T15:38:54.417+02:00  INFO 43435 --- [location-service] [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-09-23T15:38:54.418+02:00  INFO 43435 --- [location-service] [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 698 ms
2024-09-23T15:38:54.494+02:00  WARN 43435 --- [location-service] [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Failed to initialize dependency 'dataSourceScriptDatabaseInitializer' of LoadTimeWeaverAware bean 'entityManagerFactory': Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception with message: Failed to determine a suitable driver class
2024-09-23T15:38:54.495+02:00  INFO 43435 --- [location-service] [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2024-09-23T15:38:54.511+02:00  INFO 43435 --- [location-service] [  restartedMain] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-09-23T15:38:54.518+02:00 ERROR 43435 --- [location-service] [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
    If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
    If you have database settings to be loaded from a particular profile you may need to activate it (the profiles dev are currently active).


Process finished with exit code 0

PS:${EMP_CONFIG_PASSWORD}的值是我的明文密码的哈希值 => $2a$12$a.2zjPN5uKwAfi************

我的配置服务器有一个 SecurityConfiguration.java 类,如下所示:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    // Loading environment variables - Username & Password
    @Value("${EMP_CONFIG_USERNAME}")
    private String envUsername;

    @Value("${EMP_CONFIG_PASSWORD}")
    private String envPassword;

    // Password Encoder
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    // SecurityFilterChain
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{

        // Checking if username and password are available
        boolean userInMemoryAuth = !envUsername.isEmpty() && !envPassword.isEmpty();

        // Security setup based on environment
        http
                .csrf(csrf -> csrf.disable())
                .cors(cors -> cors.configurationSource(request -> {
                    var corsConfig = new CorsConfiguration();
                    corsConfig.addAllowedOrigin("http://localhost:8888");
                    corsConfig.addAllowedHeader("*");
                    corsConfig.addAllowedMethod("*");
                    corsConfig.setAllowCredentials(true);
                return corsConfig;
                }));

        if (userInMemoryAuth){
            http.authorizeHttpRequests(authorizeRequest ->
                    authorizeRequest.anyRequest().authenticated())
                    .formLogin(withDefaults());
        }else{
            http.authorizeHttpRequests(authorizeRequests ->
                    authorizeRequests.anyRequest().permitAll());
            // TODO: Add JWT Authentication setup between Gateway Service and Configuration Service
        }
        return  http.build();
    }

    // Authentication Provider - UserDetailService (InMemory)
    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager(){
        if(!envUsername.isEmpty() && !envPassword.isEmpty()){
            UserDetails user = User
                    .withUsername(envUsername)
                    .password(envPassword)
                    .roles("ADMIN")
                    .build();
            return new InMemoryUserDetailsManager(user);
        }
        return new InMemoryUserDetailsManager();
    }
}
spring spring-boot spring-data-jpa
1个回答
0
投票

我可以设法解决这个问题。在我的 SecurityConfiguration.java 中,我更改了“http.formLogin”->“http.htpBasic”。然后就成功了。

根本原因是,由于我的 Spring Security 启用了表单登录,因此无法通过邮递员或 Spring Config Client 本身的 http post 请求提交。

现在有了 Spring Security 的这个设置,它工作得很好: 安全配置.java:

package com.emp.config.security;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    // Loading environment variables - Username & Password
    @Value("${EMP_CONFIG_USERNAME}")
    private String envUsername;

    @Value("${EMP_CONFIG_PASSWORD}")
    private String envPassword;

    // Password Encoder
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    // SecurityFilterChain
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{

        // Checking if username and password are available
        boolean userInMemoryAuth = !envUsername.isEmpty() && !envPassword.isEmpty();

        // Security setup based on environment
        http
                .csrf(csrf -> csrf.disable())
                .cors(cors -> cors.configurationSource(request -> {
                    var corsConfig = new CorsConfiguration();
                    corsConfig.addAllowedOrigin("http://localhost:8888");
                    corsConfig.addAllowedOrigin("http://localhost:8080");
                    corsConfig.addAllowedHeader("*");
                    corsConfig.addAllowedMethod("*");
                    corsConfig.setAllowCredentials(true);
                return corsConfig;
                }));

        if (userInMemoryAuth){
            http.authorizeHttpRequests(authorizeRequest ->
                    authorizeRequest.anyRequest().authenticated())
                    .httpBasic(withDefaults());
        }else{
            http.authorizeHttpRequests(authorizeRequests ->
                    authorizeRequests.anyRequest().permitAll());
            // TODO: Add JWT Authentication setup between Gateway Service and Configuration Service
        }
        return  http.build();
    }

    // Authentication Provider - UserDetailService (InMemory)
    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager(){
        if(!envUsername.isEmpty() && !envPassword.isEmpty()){
            UserDetails user = User
                    .withUsername(envUsername)
                    .password(envPassword) // Encode the password here
                    .roles("ADMIN")
                    .build();
            return new InMemoryUserDetailsManager(user);
        }
        return new InMemoryUserDetailsManager();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.