为什么@RestCookie 没有检测到 ContainerRequestFilter 中为 resteasy-reactive 设置的 Cookie 标头?

问题描述 投票:0回答:0

我正在迁移我的 Kotlin Quarkus 应用程序以使用

quarkus-rest-client
quarkus-resteasy
的 Reactive 版本。

基本上,我想要一个包含 JWT 的 Cookie 创建并在用户代理上设置,如果他们没有在他们的请求中提供它到

ApiResource
中定义的任何端点(因此自定义
@NameBinding
) - 后续同一用户代理的请求将自动提供此 Cookie。

这是我之前大概的代码,使用Resteasy Classic:

import org.eclipse.microprofile.rest.client.inject.RestClient

import javax.inject.Inject
import javax.ws.rs.*
import javax.ws.rs.core.*
import javax.ws.rs.container.*
import javax.ws.rs.ext.Provider

val RESOURCE_PATH = "/api"

@NameBinding
@Retention(AnnotationRetention.RUNTIME)
annotation class JwtCookieUpserterBinder

@JwtCookieUpserterBinder
@Provider
class JwtCookieUpserter: ContainerRequestFilter, ContainerResponseFilter {
  @Inject
  @RestClient
  lateinit var jwtService: JwtClient

  override fun filter(requestContext: ContainerRequestContext) {
    var jwtCookie = requestContext?.cookies?.get("jwt")
    if (jwtCookie == null || jwtCookie.value.isNullOrEmpty()) {
      val newJwt: String = jwtService.getJwt() // returns a String
      jwtCookie = NewCookie("jwt", newJwt, RESOURCE_PATH, null, null, 600, false)
      requestContext?.headers?.add(HttpHeaders.COOKIE, jwtCookie.toString())
      requestContext?.setProperty("jwt", jwtCookie)
    }
  }

  override fun filter(requestContext: ContainerRequestContext, responseContext: ContainerResponseContext) {
    val jwtCookie = requestContext?.getProperty("jwt")
    if (jwtCookie != null) {
      responseContext?.headers?.add(HttpHeaders.SET_COOKIE, jwtCookie.toString())
    }
  }
}

@JwtCookieUpserterBinder
@Path(RESOURCE_PATH)
class ApiResource {
  // ...

  // Route meant for Testing
  @GET
  @Path("/jwt")
  @Produces(MediaType.TEXT_PLAIN)
  fun getJwt(
    @CookieParam("jwt") jwtCookieValue: String?
  ): Response {
    return Response.ok(jwtCookieValue, MediatType.TEXT_PLAIN).build()
  }

  // ... other Resource Endpoints ...
}

上面的实现工作正常。然而,切换到

resteasy-reactive
后,我注意到在
RequestFilter
中设置 Cookie HttpHeader 不再有效,我最终不得不从
ContainerRequestContext
内的
ApiResource
上的属性中提取 Cookie 值。这是我现在的代码,用于 Resteasy Reactive:

import javax.enterprise.context.ApplicationScoped
import org.eclipse.microprofile.rest.client.inject.RestClient

import javax.inject.Inject
import javax.ws.rs.*
import javax.ws.rs.core.*
import javax.ws.rs.container.*
import javax.ws.rs.ext.Provider

import org.jboss.resteasy.reactive.*
import org.jboss.resteasy.reactive.server.*

val RESOURCE_PATH = "/api"

@NameBinding
@Retention(AnnotationRetention.RUNTIME)
annotation class JwtCookieUpserterBinder

@ApplicationScoped
@Provider
class JwtCookieUpserter {
  @RestClient
  lateinit var jwtService: JwtClient

  @JwtCookieUpserterBinder
  @ServerRequestFilter
  fun filterRequest(requestContext: ContainerRequestContext?) {
    var jwtCookie = requestContext?.cookies?.get("jwt")
    if (jwtCookie == null || jwtCookie.value.isNullOrEmpty()) {
      val newJwt: String = jwtService.getJwt() // returns a String
      jwtCookie = NewCookie("jwt", newJwt, RESOURCE_PATH, null, null, 600, false)
      // requestContext?.headers?.add(HttpHeaders.COOKIE, jwtCookie.toString()) // this no longer seems to have any effect in ApiResource
      requestContext?.setProperty("set-jwt", jwtCookie)
    }
    requestContext?.setProperty("jwt", jwtCookie)
  }

  @JwtCookieUpserterBinder
  @ServerResponseFilter
  fun filterResponse(requestContext: ContainerRequestContext, responseContext: ContainerResponseContext) {
    val jwtCookie = requestContext?.getProperty("set-jwt")
    if (jwtCookie != null) {
      responseContext?.headers?.add(HttpHeaders.SET_COOKIE, jwtCookie.toString())
    }
  }
}

@JwtCookieUpserterBinder
@ApplicationScoped
@Path(RESOURCE_PATH)
class ApiResource {
  @Inject
  lateinit var requestContext: ContainerRequestContext

  // ...

  private fun getJwtCookieValueFromRequestContext(): String {
    return (requestContext.getProperty("jwt") as? Cookie)?.value ?: "Not Set"
  }

  // Route meant for Testing
  @GET
  @Path("/jwt")
  @Produces(MediaType.TEXT_PLAIN)
  fun getJwt(
    @RestCookie("jwt") jwt: String? // This still seems necessary for the Endpoint to take in the User-Agent's Cookie Value if they provide it in the Request
  ): Response {
    val jwtCookieValue = getJwtCookieValueFromRequestContext()
    return Response.ok(jwtCookieValue, MediatType.TEXT_PLAIN).build()
  }

  // ... other Resource Endpoints ...
}

我不确定这是否是完成我想要的事情的正确方法(将

ContainerRequestFilter
注入
ApiResource
Bean 看起来很奇怪);但我主要好奇为什么
@RestCookie
的行为似乎与
@CookieParam
不同。

或者,如果有人对在不添加额外依赖项的情况下完成此任务的更好方法提出建议,我也愿意接受。

kotlin quarkus resteasy
© www.soinside.com 2019 - 2024. All rights reserved.