我已经成功地生成了在Kotlin中实现的Spring Cloud Gateway(2022.0.0 - Sping Boot 3.0.0)应用程序的本机映像。
我有以下安全配置:
@EnableReactiveMethodSecurity
@Configuration(proxyBeanMethods = false)
class SecurityConfiguration(private val clientService: ClientService,
private val env: Environment) {
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http.requestCache {
it.requestCache(NoOpServerRequestCache.getInstance())
}.headers { headers ->
headers.frameOptions { frameOptions ->
frameOptions.disable()
}
}.csrf { it.disable() }
.securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
.addFilterAt(basicAuthenticationFilter(), SecurityWebFiltersOrder.HTTP_BASIC)
.authorizeExchange()
.pathMatchers("/actuator/health").permitAll()
...
.and()
.build()
}
@Bean
fun passwordEncoder(): PasswordEncoder {
return createDelegatingPasswordEncoder()
}
private fun basicAuthenticationFilter(): AuthenticationWebFilter {
val authManager = ApiAuthenticationManager(clientService)
val apiAuthenticationFilter = AuthenticationWebFilter(authManager)
return apiAuthenticationFilter
}
}
当我运行本机映像时,它崩溃,并出现以下异常:
kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Could not compute caller for function: private open fun basicAuthenticationFilter(): org.springframework.security.web.server.authentication.AuthenticationWebFilter defined in xxx.configuration.SecurityConfiguration[DeserializedSimpleFunctionDescriptor@3ff718f] (member = null)
at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:88)
at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:61)
at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:63)
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
at kotlin.reflect.jvm.internal.KFunctionImpl.getCaller(KFunctionImpl.kt:61)
at kotlin.reflect.jvm.ReflectJvmMapping.getJavaMethod(ReflectJvmMapping.kt:63)
at kotlin.reflect.jvm.ReflectJvmMapping.getKotlinFunction(ReflectJvmMapping.kt:136)
at org.springframework.core.MethodParameter$KotlinDelegate.getGenericReturnType(MethodParameter.java:914)
at org.springframework.core.MethodParameter.getGenericParameterType(MethodParameter.java:510)
at org.springframework.core.SerializableTypeWrapper$MethodParameterTypeProvider.getType(SerializableTypeWrapper.java:291)
at org.springframework.core.SerializableTypeWrapper.forTypeProvider(SerializableTypeWrapper.java:107)
at org.springframework.core.ResolvableType.forType(ResolvableType.java:1413)
at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1334)
at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1316)
at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1283)
at org.springframework.core.ResolvableType.forMethodReturnType(ResolvableType.java:1228)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:814)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:681)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:652)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1632)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:559)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:531)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:106)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:745)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565)
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
at xxx.GatewayApplicationKt.main(GatewayApplication.kt:27)
Exception in thread "main" kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Could not compute caller for function: private open fun basicAuthenticationFilter(): org.springframework.security.web.server.authentication.AuthenticationWebFilter defined in xxx.configuration.SecurityConfiguration[DeserializedSimpleFunctionDescriptor@3ff718f] (member = null)
这个调用.addFilterAt(basicAuthenticationFilter(), SecurityWebFiltersOrder.HTTP_BASIC)
,引用了一个私有函数,似乎涉及到某种Kotlin反射。
有什么办法解决这个问题吗?
1条答案
按热度按时间arknldoa1#
Spring Security使用反射来获取自定义过滤器的类,以便跟踪过滤器链中的顺序。
要将代码作为本机映像运行,需要一个反射提示来告诉GraalVM私有方法
basicAuthenticationFilter
需要在本机映像中可用。可以使用
RuntimeHintsRegistrar
添加自定义提示。在这种情况下,可以使用以下命令注册basicAuthenticationFilter
以进行反射: