Spring Boot 错误:“找不到能够从类型 [java.lang.String] 转换为类型 [....client.OAuth2ClientProperties$Registration] 的转换器”

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

application.yaml

security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: <okta issuer uri>
      client:
        registration:
          internal-client: okta
          client-id: <My- client id>
          client-secret: <My client secret>
          authorization-grant-type: client_credentails
          scope: internal
        provider:
          okta:
            issuer-uri: <okta issuer uri>
            
          
        
okta:
  oauth2:
    issuer: <okta issuer uri>
    audience: api://default

上面的代码是我的Spring Boot应用程序的application.yaml文件。


package DemoService.ConfigClasses;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.web.client.RestTemplate;

import DemoService.ConfigClasses.Interceptors.RestTemplateInterceptor;

@Configuration
public class DemoConf {

    @Autowired
    private ClientRegistrationRepository clientRegistrationRepository;
    @Autowired
    private OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepository;
    
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate= new RestTemplate();
        List<ClientHttpRequestInterceptor> interceptor=new ArrayList<>();
        interceptor.add(new RestTemplateInterceptor(manager(clientRegistrationRepository,oAuth2AuthorizedClientRepository)));
        return restTemplate;
    }
    @Bean
    public OAuth2AuthorizedClientManager manager(ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientRepository auth2AuthorizedClientRepository) {
        OAuth2AuthorizedClientProvider provider=OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials().build();
        DefaultOAuth2AuthorizedClientManager defaultOAuth2AuthorizedClientManager=new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, auth2AuthorizedClientRepository);
        defaultOAuth2AuthorizedClientManager.setAuthorizedClientProvider(provider);
        return defaultOAuth2AuthorizedClientManager;
    }

}

这是我的配置类

package DemoService.ConfigClasses;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {

    @Bean
    public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity httpSecurity) {
        httpSecurity.authorizeExchange()
                    .anyExchange()
                    .authenticated()
                    .and()
                    .oauth2ResourceServer()
                    .jwt();
        
        return httpSecurity.build();
    }
}

网络安全配置类

package DemoService.ConfigClasses.Interceptors;

import java.io.IOException;

import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;

public class RestTemplateInterceptor implements ClientHttpRequestInterceptor{

    private OAuth2AuthorizedClientManager manager;
    
    
    
    public RestTemplateInterceptor(OAuth2AuthorizedClientManager manager) {
        super();
        this.manager = manager;
    }



    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException {
        String token=manager.authorize(OAuth2AuthorizeRequest.withClientRegistrationId("internal-client").principal("internal").build()).getAccessToken().getTokenValue();
        
        request.getHeaders().add("Authorization", "Bearer "+token);
        return execution.execute(request, body);
    }
    
}


Rest 模板拦截器类

我正在尝试创建一个内部服务,并使用 okta oauth2 添加 spring security 来保护该服务。我正在为此服务实施基于令牌的授权。启动服务时显示以下错误:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.9)

2024-03-24T12:26:08.837+05:30  INFO 11772 --- [           main] DemoService.DemoServApplication          : Starting DemoServApplication using Java 17.0.3 with PID 11772 (C:\Users\lenovo\Downloads\DemoServ\DemoServ\target\classes started by lenovo in C:\Users\lenovo\Downloads\DemoServ\DemoServ)
2024-03-24T12:26:08.843+05:30  INFO 11772 --- [           main] DemoService.DemoServApplication          : No active profile set, falling back to 1 default profile: "default"
2024-03-24T12:26:10.280+05:30  WARN 11772 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration]: Error processing condition on org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientRegistrationRepositoryConfiguration
2024-03-24T12:26:10.314+05:30  INFO 11772 --- [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-03-24T12:26:10.413+05:30 ERROR 11772 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

Failed to bind properties under 'spring.security.oauth2.client.registration.internal-client' to org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties$Registration:

    Reason: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties$Registration]

Action:

Update your application's configuration
spring-boot spring-security oauth-2.0 okta
1个回答
0
投票

您的属性至少有两个错误:

  • registration
    属性下缺少一个级别(您稍后引用为
    internal-client
    的注册 ID)(这是当前异常的原因)
  • 在您的
    registration
    中,您使用
    internal-client
    (而不是
    provider
    )引用提供商

尝试:

okta-issuer: change-me
internal-client-id: change-me
internal-client-secret: change-me

security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: ${okta-issuer}
      client:
        registration:
          internal-client:
            provider: okta
            client-id: ${internal-client-id}
            client-secret: ${internal-client-secret}
            authorization-grant-type: client_credentails
            scope: internal
        provider:
          okta:
            issuer-uri: ${okta-issuer}
© www.soinside.com 2019 - 2024. All rights reserved.