无法使用 keycloak 构建基于 spring 的项目进行身份验证

Posted

技术标签:

【中文标题】无法使用 keycloak 构建基于 spring 的项目进行身份验证【英文标题】:Unable to build spring based project for authentication using keycloak 【发布时间】:2020-01-17 07:12:18 【问题描述】:

问题陈述

我无法通过 spring boot 项目构建,我想通过它来保护我的应用程序。钥匙披风。

预期输出

项目构建成功,当我点击其余 URL 时,它将重定向到密钥斗篷页面进行身份验证。

EmployeeRestController

@RestController
public class EmployeeRestController 

  @GetMapping(path = "/username")
  public String getAuthorizedUserName() 
    return "Username Returned";
  

  @GetMapping(path = "/roles")
  public String getAuthorizedUserRoles() 
    return "Roles Returned";
  

启动

@SpringBootApplication
public class Startup 

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

应用程序属性

server.port=8085

keycloak.realm=wow
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.resource=wow-client
keycloak.public-client=true
keycloak.securityConstraints[0].authRoles[0]=user
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/*

pom.xml

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-spring-boot-starter -->
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-spring-boot-starter</artifactId>
        <version>7.0.0</version>
    </dependency>
</dependencies>

错误日志

2019-09-16 17:44:24.525  INFO 10396 --- [           main] com.diwakar.Startup                      : Starting Startup on diwakarb with PID 10396 (started by diwakarb in E:\DB Godam\Sample-KeyCloak-Project)
2019-09-16 17:44:24.527  INFO 10396 --- [           main] com.diwakar.Startup                      : No active profile set, falling back to default profiles: default
2019-09-16 17:44:25.419  WARN 10396 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tomcatServletWebServerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration$EmbeddedTomcat.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.keycloak.adapters.springboot.KeycloakAutoConfiguration': Unsatisfied dependency expressed through method 'setKeycloakSpringBootProperties' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: 
2019-09-16 17:44:25.429  INFO 10396 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-09-16 17:44:25.531 ERROR 10396 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

Parameter 1 of method setKeycloakSpringBootProperties in org.keycloak.adapters.springboot.KeycloakBaseSpringBootConfiguration required a bean of type 'org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver' that could not be found.


Action:

Consider defining a bean of type 'org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver' in your configuration.


Process finished with exit code 1

注意:请注意密钥披风配置正确

【问题讨论】:

对我来说同样的问题,当我定义 bean 时,我收到:创建名称为“keycloakConfigResolver”的 bean 时出错:当前正在创建请求的 bean:是否存在无法解析的循环引用?使用 Spring-Boot 2.1.8 / keycloak-spring-boot-starter 7.0.0。您可以编辑并添加您正在使用的 Spring-Boot 版本吗? 【参考方案1】:

关于循环依赖问题的说明。

在我将 Spring Boot Web 从 Tomcat 切换到 Jetty 后,我的 public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapterKeycloakSpringBootConfigResolver 之间存在无法解析的循环依赖关系,出现异常(请参阅 https://***.com/a/66297192/8534088)。

Spring Boot 应用启动时的异常如下所示:

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfiguration': Unsatisfied dependency expressed through field 'keycloakConfigResolver'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'keycloakConfigResolver': Requested bean is currently in creation: Is there an unresolvable circular reference

为了修复无法解析的循环依赖,我改了

@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)

@ComponentScan(basePackageClasses = KeycloakSpringBootConfigResolver.class)

在我的SecurityConfiguration 课堂上。

初始配置取自https://www.baeldung.com/spring-boot-keycloak#securityconfig。

【讨论】:

【参考方案2】:

这是 Keycloak Spring Boot Adapter 的一个已知问题,从版本 7.0.0 开始。它已在此相关问题中得到解决:Issues running example keycloak spring-boot app 并记录在 Jira 项目中:https://issues.jboss.org/browse/KEYCLOAK-11282

另一种解决方案是使用显式 KeycloakSpringBootProperties 参数声明自定义 KeycloakSpringBootConfigResolver bean,这使得 Spring Boot 可以正确读取 application.properties 文件中的 Keycloak 配置。

@Configuration
public class MyKeycloakSpringBootConfigResolver extends KeycloakSpringBootConfigResolver 
    private final KeycloakDeployment keycloakDeployment;

    public MyKeycloakSpringBootConfigResolver(KeycloakSpringBootProperties properties) 
        keycloakDeployment = KeycloakDeploymentBuilder.build(properties);
    

    @Override
    public KeycloakDeployment resolve(HttpFacade.Request facade) 
        return keycloakDeployment;
    

如果还使用 Spring Security,那么您还需要在安全配置类中定义这个主 bean,返回您的自定义 KeycloakSpringBootConfigResolver bean。

@Bean
@Primary
public KeycloakConfigResolver keycloakConfigResolver(KeycloakSpringBootProperties properties) 
    return new MyKeycloakSpringBootConfigResolver(properties);

【讨论】:

【参考方案3】:

我在使用 springboot-2.2.0/keycloak-7.0.1 时遇到了同样的问题。 我将 bean KeycloakSpringBootConfigResolver 移动到另一个配置文件,它可以工作。

@Configuration
public class BeanKeycloakConfiguration 
    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() 
        return new KeycloakSpringBootConfigResolver();
    
`

【讨论】:

以上是关于无法使用 keycloak 构建基于 spring 的项目进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何在基于 Keycloak/Spring 的应用程序中实现单点注销?

使用 KeycloakAutoConfiguration 无法使用 Spring Boot Security UnsatisfiedDependencyException 设置 Keycloak

Spring Boot 我无法切换 keycloak 和基本身份验证

Keycloak:无法在 Spring Boot 应用程序中加载 URL

Keycloak Spring boot 后端和 Angular 前端,CORS 错误

Spring Boot - 无法通过 Zuul 代理获得 Keycloak 授权 api 的响应