我有一个来自边服的网络挂钩,我试着在控制器前面做一个过滤器,以判断签名.像是一种Spring Security风格,但不幸的是,它是带有react 堆的Quarkus. 在控制器中,我有null个,调试器甚至没有实现控制器的方法.

我的目标是:

  1. 判断签名我需要一个头和主体,WebhookHandlerUtility不是mt类,我不能更改它.和WebhookHandlerUtility.verifySignature(signature, body)同步方法,我不能更改它.
  2. 我需要重写流,因为我希望在控制器中以主体的形式接收该数据.

我的实现有什么问题以及如何修复它?

@Provider
class SignatureFilter(
        private val objectMapper: ObjectMapper,
        private val webhookHandlerUtility: WebhookHandlerUtility
) : ContainerRequestFilter {

    private val executor = Executors.newFixedThreadPool(5)

    @Throws(IOException::class)
    override fun filter(requestContext: ContainerRequestContext) {
        executor.execute {
            val signature = requestContext.getHeaderString("signature")
            val body = requestContext.entityStream.reader().readText()

            if (!webhookHandlerUtility.verifySignature(signature, body)) {
                throw TerraSignatureVerificationException()
            }

            val payload = webhookHandlerUtility.parseWebhookPayload(body)
                    ?: throw TerraWebHookPayloadParseException()

            val json = objectMapper.writeValueAsString(payload.raw)
            val newInputStream = ByteArrayInputStream(json.toByteArray())

            requestContext.entityStream = newInputStream
        }
    }
}

@ApplicationScoped
@Path("/webHook")
class WebHookController(
        private val omronService: OmronService
) {

    @POST
    @Path("/device")//, 
    @Consumes(MediaType.APPLICATION_JSON)
    fun omronWebHook(req: HookDto): Uni<Response> {
        log.info("Received data: $req")
        return omronService.save(req)
                .map { Response.noContent().build() }
    }
}
2023-09-29 14:30:46,346 DEBUG [org.jbo.res.rea.ser.han.ParameterHandler] (vert.x-eventloop-thread-0) Error occurred during parameter extraction: 
javax.enterprise.inject.UnsatisfiedResolutionException: No bean found for required type [interface javax.ws.rs.container.ContainerRequestContext] and qualifiers [[]]
    at io.quarkus.arc.impl.InstanceImpl.bean(InstanceImpl.java:190)
    at io.quarkus.arc.impl.InstanceImpl.getInternal(InstanceImpl.java:211)
    at io.quarkus.arc.impl.InstanceImpl.get(InstanceImpl.java:97)
    at org.jboss.resteasy.reactive.server.core.parameters.ContextParamExtractor.extractParameter(ContextParamExtractor.java:100)
    at org.jboss.resteasy.reactive.server.handlers.ParameterHandler.handle(ParameterHandler.java:45)
    at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:111)
    at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:142)
    at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:51)
    at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:18)
    at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:8)
    at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
    at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:84)
    at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:71)
    at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
    at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:430)
    at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:408)
    at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:196)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:185)
    at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
    at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)

2023-09-29 14:30:46,349 DEBUG [org.jbo.res.rea.com.cor.AbstractResteasyReactiveContext] (vert.x-eventloop-thread-0) Restarting handler chain for exception exception: 
javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
    at org.jboss.resteasy.reactive.server.handlers.ParameterHandler.handle(ParameterHandler.java:66)
    at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:111)
    at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:142)
    at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:51)
    at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:18)
    at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:8)
    at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
    at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:84)
    at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:71)
    at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
    at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:430)
    at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:408)
    at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:196)
    at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:185)
    at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
    at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: No bean found for required type [interface javax.ws.rs.container.ContainerRequestContext] and qualifiers [[]]
    at io.quarkus.arc.impl.InstanceImpl.bean(InstanceImpl.java:190)
    at io.quarkus.arc.impl.InstanceImpl.getInternal(InstanceImpl.java:211)
    at io.quarkus.arc.impl.InstanceImpl.get(InstanceImpl.java:97)
    at org.jboss.resteasy.reactive.server.core.parameters.ContextParamExtractor.extractParameter(ContextParamExtractor.java:100)
    at org.jboss.resteasy.reactive.server.handlers.ParameterHandler.handle(ParameterHandler.java:45)
    ... 30 more

2023-09-29 14:30:46,358 INFO  [http-problem] (vert.x-eventloop-thread-0) status=400, title="Bad Request", detail="HTTP 400 Bad Request" 
Exception in thread "pool-6-thread-1" java.lang.IllegalStateException: Cannot be called from response filter
    at org.jboss.resteasy.reactive.server.jaxrs.ContainerRequestContextImpl.assertNotResponse(ContainerRequestContextImpl.java:94)
    at org.jboss.resteasy.reactive.server.jaxrs.ContainerRequestContextImpl.setEntityStream(ContainerRequestContextImpl.java:158)
    at com.dfskjhzxk.terra.configuration.SignatureFilter.filter$lambda$0(SignatureFilter.kt:41)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)

推荐答案

问题是,您试图从不受Quarkus管理的线程访问请求范围的Bean(因为您正在使用自己的执行器).

一种简单的补救方法是在filter方法本身中只访问ContainerRequestContext中需要的任何内容,而不是在用作线程Runnable的lambda中访问前者

Kotlin相关问答推荐

Lambda和普通Kotlin函数有什么区别?

判断字符串是否除了.&" ",","@""""

Kotlin -从列表中获取特定过滤器的唯一列表值

在 Kotlin 中,为什么我们要在闭包中捕获值

创建包含 3 个相同项目的列表/使用返回类型重复

修改器的属性是什么,我需要更改以使角变圆且宽度更小?喷气背包组合

如何使用函数类型或 lambdas 作为 Kotlin 上下文接收器的类型?

在子类中覆盖 kotlin 运算符扩展函数

在 SplashActivity 中显示的 Firebase 应用内消息.如何在 MainActivity 中显示它?

Kotlin 语言是如何用 Kotlin 编写的?

Kotlin:如何在活页夹中返回正在运行的服务实例?

requireNotNull vs sure !! 操作符

Kotlin:什么是 kotlin.String!类型

Kotlin惰性默认属性

如何暂停kotlin coroutine直到收到通知

应用程序在使用 Google Play 服务时遇到问题

@StringRes、@DrawableRes、@LayoutRes等android注释使用kotlin参数进行判断

Kotlin类型安全类型别名

如何在 spring-boot Web 客户端中发送请求正文?

使用 Kotlin 按字母对数组进行排序