使用“spring-boot-starter-oauth2-resource-server”设置资源服务器时,不会自动注入 JwtDecoder bean
Posted
技术标签:
【中文标题】使用“spring-boot-starter-oauth2-resource-server”设置资源服务器时,不会自动注入 JwtDecoder bean【英文标题】:JwtDecoder bean is not injected automatically while setting a ressource server using 'spring-boot-starter-oauth2-resource-server' 【发布时间】:2021-10-26 10:02:57 【问题描述】:我正在使用“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)
所以这里的问题是 JwtDecoder bean 找不到,即使它在 OAuth2ResourceServerJwtConfiguration 类中声明并且受我在 application.yml 中设置的 issuer-uri 的限制。
作为一种解决方法,我自己重新声明了 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'
【问题讨论】:
你很可能不需要导入,oauth 已经包含在 spring security 中。尝试删除导入。 你使用的是什么版本的 Spring Boot? @SteveRiesenberg 我正在使用 Spring Boot 的“2.3.4.RELEASE”版本 @Toerktumlare oauth2-resource-server 不包含在 spring security 中,至少从与 spring boot 2.3.4.RELEASE 捆绑在一起的 5.2.2 版本开始 @youneselmorabit,升级到2.3.12.RELEASE
后有什么变化吗?日志中还有其他错误吗? issuer-uri 似乎无效或无法解析(例如 UnknownHostException、SocketTimeoutException 等)。
【参考方案1】:
我发现我正在处理的项目的 gradle 配置存在问题(更新了问题)。 Spring Boot 依赖项是使用版本“2.3.4.RELEASE”声明的,而 org.springframework.boot
插件版本是“2.2.5.RELEASE”,我认为这一定导致了 spring 依赖项之间的某种不兼容。
作为解决方案,我从 spring 依赖项中删除了版本声明,并将插件版本设置为“2.3.4.RELEASE”,现在错误消失了,oauth2 资源服务器配置无需任何额外配置即可工作。
注意:
我注意到,当我将插件版本保持在“2.2.5.RELEASE”时,错误仍然存在,除非我删除插件io.spring.dependency-management
,否则开箱即用的配置不起作用。
【讨论】:
以上是关于使用“spring-boot-starter-oauth2-resource-server”设置资源服务器时,不会自动注入 JwtDecoder bean的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)