spring-boot - 使用“spring-boot-starter-oauth2-resource-server”设置资源服务器时,不会自动注入 JwtDecoder bean
问题描述
我正在使用“spring-boot-starter-oauth2-resource-server”设置资源服务器:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-resource-server'
我设置了一个简单的安全配置,如下所示:
@Configuration
@EnableWebSecurity
class EndpointsSecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(web: WebSecurity) {
web.ignoring().antMatchers("/live")
}
override fun configure(http: HttpSecurity?) {
http?.cors()
http?.sessionManagement()?.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
http?.csrf()?.disable()
http
?.authorizeRequests()
?.anyRequest()
?.authenticated()
?.and()
?.oauth2ResourceServer()
?.jwt()
}
}
在我的 application.yml 中,我添加了 issuer-uri,如下所示:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://cognito-idp.${AWS_REGION:eu-central-1}.amazonaws.com/${COGNITO_USER_POOL_ID:testUserPoolId}
正如我在许多教程和官方文档中看到的那样,这个配置是简约的,应该可以在没有任何额外配置的情况下开箱即用,但是我的应用程序无法启动并出现以下错误:
Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.oauth2.jwt.JwtDecoder' available
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
所以这里的问题是,即使在 OAuth2ResourceServerJwtConfiguration 类中声明了 JwtDecoder bean 并且受我在 application.yml 中设置的 issuer-uri 条件限制,也找不到 JwtDecoder bean。
作为一种解决方法,我自己重新声明了 bean,如下所示:
@Configuration
@EnableWebSecurity
class EndpointSecurityConfig(@Value("\${spring.security.oauth2.resourceserver.jwt.issuer-uri}") private val issuerUri: String) : WebSecurityConfigurerAdapter() {
override fun configure(web: WebSecurity) {
web.ignoring().antMatchers("/live")
}
override fun configure(http: HttpSecurity?) {
http?.cors()
http?.sessionManagement()?.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
http?.csrf()?.disable()
http
?.authorizeRequests()
?.anyRequest()
?.authenticated()
?.and()
?.oauth2ResourceServer()
?.jwt()
}
@Bean
@Conditional(IssuerUriCondition::class)
fun jwtDecoderByIssuerUri(): JwtDecoder? {
return JwtDecoders.fromIssuerLocation(issuerUri)
}
}
这是有效的,但我无法弄清楚为什么开箱即用的配置对我不起作用?
更新:gradle 配置
plugins {
id 'java'
id "io.spring.dependency-management" version "1.0.9.RELEASE"
id "org.springframework.boot" version "2.2.5.RELEASE"
id "org.owasp.dependencycheck" version "6.0.2"
}
// irrelevent details
dependencies {
ktlint "com.pinterest:ktlint:0.34.2"
implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: '1.3.70'
implementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: '1.3.70'
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.3.0'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter', version: '2.3.4.RELEASE'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.4.RELEASE'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-log4j2', version: '2.3.4.RELEASE'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '2.3.4.RELEASE'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.3.4.RELEASE'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '2.3.4.RELEASE'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-resource-server', version: '2.3.4.RELEASE'
implementation group: 'com.amazonaws', name: 'aws-java-sdk-secretsmanager', version: "1.11.875"
implementation group: 'com.oracle.database.jdbc', name: 'ojdbc8', version: "19.7.0.0"
implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-kotlin', version: '2.10.2'
implementation group: 'org.springdoc', name: 'springdoc-openapi-kotlin', version: '1.4.3'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.4.3'
runtime group: 'com.h2database', name: 'h2', version: '1.4.194'
testImplementation group: 'io.mockk', name: 'mockk', version: '1.9.3'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.3.4.RELEASE'
testImplementation group:'org.springframework.security', name: 'spring-security-test'
}
解决方案
我发现我正在处理的项目的 gradle 配置存在问题(更新了问题)。Spring Boot 依赖项是使用版本“2.3.4.RELEASE”声明的,而org.springframework.boot
插件版本是“2.2.5.RELEASE”,我认为这一定导致了 spring 依赖项之间的某种不兼容。
作为解决方案,我从 spring 依赖项中删除了版本声明,并将插件版本设置为“2.3.4.RELEASE”,现在错误消失了,oauth2 资源服务器配置可以在没有任何额外配置的情况下工作。
注意:
I noticed that when I keep the plugin version at "2.2.5.RELEASE" the error persist and the out of the box config doesn't work unless I remove the plugin io.spring.dependency-management
.
推荐阅读
- node.js - 成功部署的应用程序无法访问 POSTGRES - HEROKU
- python - 如何避免在 Python 中为变量分配任何内容?
- ckeditor - 向ckeditor5 onchange中的元素添加属性
- javascript - NextJS:使用自定义服务器(NestJS)呈现特定页面
- cmake - 使用 cpack 时设置 CMAKE_INSTALL_PREFIX
- javascript - 函数作为带参数的函数的参数
- arrays - 使用复选框进行反应过滤
- r - 手动将图例添加到 ggplot2 绘图
- java - 附加多个视频但结果无法打开
- ffmpeg - 希望 ffmpeg 仅捕获系统声音(无麦克风)