使用 KeycloakAutoConfiguration 无法使用 Spring Boot Security UnsatisfiedDependencyException 设置 Keycloak
Posted
技术标签:
【中文标题】使用 KeycloakAutoConfiguration 无法使用 Spring Boot Security UnsatisfiedDependencyException 设置 Keycloak【英文标题】:Fail to setup Keycloak with Spring Boot Security UnsatisfiedDependencyException with KeycloakAutoConfiguration 【发布时间】:2019-04-04 20:23:49 【问题描述】:keycloack 和 spring 安全性有点问题。
这里是 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.world</groupId>
<artifactId>having-fun</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>having-fun</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<keycloak.version>4.5.0.Final</keycloak.version>
<kotlin.version>1.2.70</kotlin.version>
<swagger.version>2.9.2</swagger.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-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>$swagger.version</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>$swagger.version</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>$keycloak.version</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<sourceDirectory>$project.basedir/src/main/kotlin</sourceDirectory>
<testSourceDirectory>$project.basedir/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>development</profile>
<profile>docker</profile>
</profiles>
</configuration>
</plugin>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
<plugin>jpa</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>$kotlin.version</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>$kotlin.version</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
这是错误
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.1.0.RELEASE:run (default-cli) on project activation-service-backend: An exception occurred while running. null: InvocationTargetException: 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 'setKeycloakConfigResolvers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': 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? -> [Help 1]
知道什么是错的......我相信它来自 pom.xml 但我不知道为什么? 提前谢谢
多亏了这个 ***** 规则,我必须提供更多细节,即使现有的细节不多。所以我创建了一些没有任何内容的文本。如果你读到这里,请停下来,因为只有字母,没有信息……现在让我们试试,如果我写够了
【问题讨论】:
Keycloak 4.5.0 不是针对 2.1.0 启动 (github.com/keycloak/keycloak/blob/4.5.0.Final/adapters/oidc/…) 构建的,因此如果您可以检查旧版本的启动可能有助于缩小问题范围。您也可以尝试 jetty 或 undertow 来查看该错误是否特定于默认嵌入式 tomcat 我有 spring boot 2.1.0.RELEASE 和 Keycloak 4.5 集成工作,但我没有使用任何 keycloak jars。请参阅此处的文档 keycloak.org/docs/latest/securing_apps/… 和 keycloak.org/docs/latest/securing_apps/… 另外,如果你正在构建资源服务器,我建议使用 Spring 5.1 安全特性来设置资源服务器。 我已经阅读了@ChirdeepTomar 的文档,但我看不出做错了什么......甚至添加他们提到的这个过滤器注册bean .. 是否可以只使用简单的 OAuth 和 Keycloak 和 Spring Boot Security? @RyanDawson 我也尝试过使用 spring boot 2.0.3 但它也不起作用...... 【参考方案1】:确保您在 build.gradle 或 pom.xml 中有以下依赖项
"org.springframework.boot:spring-boot-starter-web",
"org.springframework.boot:spring-boot-starter-security",
"org.springframework.security:spring-security-oauth2-jose",
"org.springframework.security.oauth:spring-security-oauth2:2.3.4.RELEASE",
"org.springframework.security:spring-security-oauth2-resource-server"
应用程序.yaml
spring:
application:
name: sociter
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: http://localhost:8080/auth/realms/REALM_NAME/protocol/openid-connect/certs
issuer-uri: http://localhost:8080/auth/realms/REALM_NAME
并在此处设置网络安全:
https://github.com/jzheaux/messaging-app/blob/master/resource-server/src/main/java/sample/config/ResourceServerConfig.java
更多详情:https://spring.io/blog/2018/08/21/spring-security-5-1-0-rc1-released#oauth2-resource-server
【讨论】:
谢谢 .. 但是如果我还想提供从 REST API 登录的可能性,那么我必须像客户端一样行事吗?不仅仅是资源服务器? 阅读 Keycloak 客户端上的 Access_Type。 REST API 是受 Bearer Token 保护的后端服务,因此您无法登录 API,您需要在 Authorization 标头中传入 Bearer Token 才能访问 API。文档:keycloak.org/docs/latest/server_admin/index.html#oidc-clients 很抱歉问的有点愚蠢......我想要的是一个带有 REST API 的微服务,它由 Spring Security 使用 OAuth2 和例如用于身份验证的密钥斗篷。如果没有提供有效的 JWT,微服务应该重定向到 keycloak,并希望返回一个有效的 JWT。这有什么不对吗?目前我有点迷茫:-) 别担心 :) 执行重定向不是微服务的责任,微服务只是一个后端 API,它只需要来自某些 OIDC 提供商(如 Keycloak、Okta、Auth0 或 AzureAD)的有效令牌。您将 JWT 传递到 Spring Boot 微服务中,无论是 SPA、移动应用程序还是桌面应用程序,您的前端都将使用 Keycloak 进行身份验证以获取该 JWT 令牌。无论是重定向还是从 SPA 到令牌端点的调用,都取决于您正在构建的客户端类型。 邮递员:你应该叫这个 curl -X POST \ localhost:8080/auth/realms/test-realm/protocol/openid-connect/… \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'Postman-Token: 90787d63-46e4-4da0-a464-c7094a5b27e7' \ -H 'cache-control: no-cache' \ -d 'grant_type=password&client_id=postman-client&password=112&scope=openid%20email%20profile&username=test-admin'以上是关于使用 KeycloakAutoConfiguration 无法使用 Spring Boot Security UnsatisfiedDependencyException 设置 Keycloak的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)