You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus中如何将WebSocket的JWT查询参数转为Authorization头

在Quarkus中通过查询参数为WebSocket注入Authorization头实现认证

问题背景

基于Quarkus开发时,需要将WebSocket请求查询参数里的jwt值转换为Authorization: Bearer <JWT>请求头。由于WebSocket客户端是浏览器,无法直接设置请求头。

尝试过的无效方案

我编写了一个Scala请求过滤器,但它仅对REST API生效,WebSocket握手请求不会触发该过滤器:

class WebSocketJwtFilter:
    @ServerRequestFilter(preMatching = true)
    def preMatchingFilter(ctx: ContainerRequestContext): Unit =
        val info = ctx.getUriInfo
        val path = info.getPath

        if path.startsWith("/ws/") then
            val jwt = info.getQueryParameters.getFirst("jwt")

            if jwt != null && !jwt.isBlank then
                ctx.getHeaders.putSingle("Authorization", s"Bearer $jwt")

期望实现

不想在@WebSocket类中手动处理认证逻辑,希望借助Quarkus安全机制,实现类似以下的WebSocket认证效果,直接使用@RolesAllowed和@Claim这类注解完成权限控制与Claims注入:

@WebSocket(path = "/ws/v1/foo")
@RequestScoped
@RolesAllowed(Array("user"))
class RtcWs:
    @Inject
    @Claim(standard = sub)
    private[poc] var subject: String = uninitialized

解决方案

Quarkus的@ServerRequestFilter默认仅处理REST端点,要让它作用于WebSocket握手请求,需做以下调整:

1. 修改过滤器,指定匹配WebSocket路径

给过滤器添加@MatchingPath注解,明确匹配WebSocket路径前缀,确保握手请求被拦截,同时声明正确的作用域:

import jakarta.ws.rs.container.ContainerRequestContext
import jakarta.ws.rs.container.ServerRequestFilter
import jakarta.ws.rs.core.UriInfo
import jakarta.ws.rs.MatchingPath
import jakarta.enterprise.context.ApplicationScoped

@ApplicationScoped
class WebSocketJwtFilter:
    @ServerRequestFilter(preMatching = true)
    @MatchingPath("/ws/*")
    def preMatchingFilter(ctx: ContainerRequestContext): Unit =
        val info: UriInfo = ctx.getUriInfo
        val jwt = info.getQueryParameters.getFirst("jwt")
        if jwt != null && !jwt.isBlank then
            ctx.getHeaders.putSingle("Authorization", s"Bearer $jwt")

2. 确保项目引入JWT安全扩展

要让@RolesAllowed和@Claim生效,需确保项目已引入Quarkus JWT扩展:

  • Maven依赖:
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-jwt</artifactId>
</dependency>
  • Gradle依赖:
implementation 'io.quarkus:quarkus-smallrye-jwt'

3. 验证逻辑

当WebSocket发起握手请求时,过滤器会拦截所有路径以/ws/开头的请求,提取jwt查询参数并注入Authorization头。之后Quarkus安全机制会自动完成JWT验证、Claims解析,以及@RolesAllowed的权限检查,最终你的RtcWs类就能正常注入subject并实现权限控制。

内容的提问来源于stack exchange,提问作者wiradikusuma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 00:33:29