oauth2 和 securityconfig 的 spring 错误异常

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

早上好, 我正在重做一个演示,但有一个编译错误,我有 3 个异常,它们都有一个链接:抛出异常并显示消息:authorizationUri 不能为空。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig' defined in file [C:\Users\chres\Documents\jetBrainProjects\intellij-idea-projects\sdia2\target\classes\com\example\sdia2\secu\SecurityConfig.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'clientRegistrationRepository' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientRegistrationRepositoryConfiguration.class]: Failed to instantiate [org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository]: Factory method 'clientRegistrationRepository' threw exception with message: **authorizationUri cannot be empty**
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:797) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:236) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1350) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1187) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:558) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:518) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:949) ~[spring-context-6.0.16.jar:6.0.16]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:615) ~[spring-context-6.0.16.jar:6.0.16]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.8.jar:3.1.8]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:738) ~[spring-boot-3.1.8.jar:3.1.8]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:440) ~[spring-boot-3.1.8.jar:3.1.8]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:324) ~[spring-boot-3.1.8.jar:3.1.8]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1317) ~[spring-boot-3.1.8.jar:3.1.8]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-3.1.8.jar:3.1.8]
    at com.example.sdia2.Sdia2Application.main(Sdia2Application.java:15) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.1.8.jar:3.1.8]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientRegistrationRepository' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientRegistrationRepositoryConfiguration.class]: Failed to instantiate [org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository]: Factory method 'clientRegistrationRepository' **threw exception with message: authorizationUri cannot be empty**
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1330) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:558) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:518) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:906) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:784) ~[spring-beans-6.0.16.jar:6.0.16]
    ... 22 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository]: Factory method **'clientRegistrationRepository' threw exception with message: authorizationUri cannot be empty**
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.0.16.jar:6.0.16]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:646) ~[spring-beans-6.0.16.jar:6.0.16]
    ... 36 common frames omitted
Caused by: java.lang.IllegalArgumentException: **authorizationUri cannot be empty**
    at org.springframework.util.Assert.hasText(Assert.java:294) ~[spring-core-6.0.16.jar:6.0.16]
    at org.springframework.security.oauth2.client.registration.ClientRegistration$Builder.validateAuthorizationCodeGrantType(ClientRegistration.java:660) ~[spring-security-oauth2-client-6.1.6.jar:6.1.6]
    at org.springframework.security.oauth2.client.registration.ClientRegistration$Builder.build(ClientRegistration.java:610) ~[spring-security-oauth2-client-6.1.6.jar:6.1.6]
    at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper.getClientRegistration(OAuth2ClientPropertiesMapper.java:87) ~[spring-boot-autoconfigure-3.1.8.jar:3.1.8]
    at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper.lambda$asClientRegistrations$0(OAuth2ClientPropertiesMapper.java:65) ~[spring-boot-autoconfigure-3.1.8.jar:3.1.8]
    at java.base/java.util.HashMap.forEach(HashMap.java:1429) ~[na:na]
    at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper.asClientRegistrations(OAuth2ClientPropertiesMapper.java:64) ~[spring-boot-autoconfigure-3.1.8.jar:3.1.8]
    at org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientRegistrationRepositoryConfiguration.clientRegistrationRepository(OAuth2ClientRegistrationRepositoryConfiguration.java:49) ~[spring-boot-autoconfigure-3.1.8.jar:3.1.8]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ~[spring-beans-6.0.16.jar:6.0.16]
    ... 37 common frames omitted

应用程序.属性

spring.application.name=customer-app
server.port=8084
spring.security.oauth2.client.registration.google.client-id=290479700275-7t9jjpd5agua1u7n881fubvd2ceqg7aq.apps.googleusercontent.com
spring.security.oauth2.client.registration.google.client-secret=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
spring.security.oauth2.client.provider.github.user-name-attribute=login

spring.security.oauth2.client.registration.github.client-id=Iv1.3369f41e3d67c0a3
spring.security.oauth2.client.registration.github.client-secret=f7cb85296f581390511d1bf4aa29bcc43af7b163
spring.security.oauth2.client.provider.google.user-name-attribute=email
spring.datasource.url=jdbc:h2:mem:customers-db
spring.h2.console.enabled=true

spring.security.oauth2.client.registration.keycloak.client-name=keycloak
spring.security.oauth2.client.registration.keycloak.client-id=client-cree-customer
spring.security.oauth2.client.registration.keycloak.client-secret=C6JJFHCOkDSvaZwLAy673yHVnXkDu6k3
spring.security.oauth2.client.registration.keycloak.scope=openid, profile, email, offline_access
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.redirect-uri=http://localhost:8084/login/oauth2/code/sdia3
spring.security.oauth2.client.registration.keycloak.issuer-uri=http://localhost:8080/realms/sdia3/account
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username
    @Controller   
    public class CustomerController {
        /**
         * acces a interface
         */
        private  CustomerRepository customerRepository;
        public CustomerController(CustomerRepository customerRepository) {
            this.customerRepository = customerRepository;
        }

        @GetMapping("/customers")
        @PreAuthorize("hasAuthority('ADMIN')")

        public String customers(Model model){  
            List<Customer> customersList = customerRepository.findAll();
            model.addAttribute("customers", customersList);
            return "customers";
        }

        @GetMapping("/products")
        public String products(Model model){
            return "products";
        }

        
        @GetMapping("/auth")
        @ResponseBody//vu que ce n'est pas un rest controller, il doit y avoir cette anotation pour retourner la reponse sous format json
        public Authentication auth(Authentication authentication){
            return authentication;
        }
        
        @GetMapping("/")
        public String index(){
            return "index";
        }
}

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sdia2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sdia2</name>
    <description>sdia2</description>
    <properties>
        <java.version>21</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity6 -->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity6</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.maven.shared/maven-dependency-tree -->
        <dependency>
            <groupId>org.apache.maven.shared</groupId>
            <artifactId>maven-dependency-tree</artifactId>
            <version>3.2.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-messaging -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-messaging</artifactId>
            <version>6.2.3</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>3.1.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.2.224</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>5.3.2</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>
        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-clean-plugin</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.11.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

安全配置

@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)

public class SecurityConfig {
    //stock les diff providers conf dans l'appli pour la connection clients
    private final ClientRegistrationRepository clientRegistrationRepository;
    //inj de dependance via constructeur
    public SecurityConfig(ClientRegistrationRepository clientRegistrationRepository){
        this.clientRegistrationRepository=clientRegistrationRepository;
    }

    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(Customizer.withDefaults())//config par def.
                .authorizeHttpRequests(ar-> ar.anyRequest().authenticated())//toutes requetes necessite une authentification
                .authorizeHttpRequests(ar->ar.requestMatchers("/","/webjars/**","/h2-console/**").permitAll())//toute url sans besoin de s'authentifier:parefeu
                .oauth2Login(Customizer.withDefaults())
                .logout((logout)->logout
                        .logoutSuccessHandler(oidcLogoutSuccessHandler())
                        .logoutSuccessUrl("/").permitAll()
                        .clearAuthentication(true)
                        .deleteCookies("JSESSIONID"));
        return http.build();

    }

    private OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler() {
        final OidcClientInitiatedLogoutSuccessHandler oidcClientInitiatedLogoutSuccessHandler=
                new OidcClientInitiatedLogoutSuccessHandler(this.clientRegistrationRepository);
        oidcClientInitiatedLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}?logoutsuccess=true");
        return oidcClientInitiatedLogoutSuccessHandler;
    }
}

主要

@SpringBootApplication
public class Sdia2Application {

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


//s'execute au demarrage=onInit() avec en para l'int customerrepository pour utiliser ses methodes REST=inj dep
    @Bean
    CommandLineRunner commandLineRunner(CustomerRepository customerRepository) {
        return args -> {
            customerRepository.save(Customer.builder().name("casfr").email("[email protected]").build());
            customerRepository.save(Customer.builder().name("chrissdf").email("[email protected]").build());
            customerRepository.save(Customer.builder().name("lor").email("[email protected]").build());

        };
    }
}

客户存储库

public interface CustomerRepository  extends JpaRepository<Customer, Long> {

}

我在我的属性文件中明确定义了这一点:

spring.security.oauth2.client.registration.keycloak.redirect-uri=http://localhost:8084/login/oauth2/code/sdia3
spring.security.oauth2.client.registration.keycloak.issuer-uri=http://localhost:8080/realms/sdia3/account

这还不够吗?

spring exception oauth-2.0 uri
1个回答
0
投票

您没有正确设置

spring.security.oauth2.client.provider.keycloak
:只有
user-name-attribute
存在,这是不够的。

由于 Keycloak 符合 OIDC 标准,因此将

spring.security.oauth2.client.provider.keycloak.issuer-uri=
设置为您的令牌之一中 iss
 声明的
精确值
应该足够了(Spring 将从
.well-known/openid-configuration
中提取其余的conf)。

© www.soinside.com 2019 - 2024. All rights reserved.