早上好, 我正在重做一个演示,但有一个编译错误,我有 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.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)。