【发布时间】: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 等)。
标签: spring-boot kotlin spring-security oauth-2.0 jwt