如何在Quarkus中自定义Unauthorized(未授权)响应?
我们需要统一自定义错误响应格式,其中Forbidden场景已实现,但Unauthorized始终无法触发自定义逻辑。尝试了三种方案均未生效,相关代码如下:
尝试过的方案
方案一:ServerExceptionMapper
@ServerExceptionMapper @Priority(1) fun unauthorized(e: UnauthorizedException) = mapExceptionIntoError(Response.Status.UNAUTHORIZED, "UNAUTHORIZED", e.message)
方案二:ExceptionMapper
@Provider @Priority(Priorities.AUTHORIZATION) class UnauthorizedErrorMapper : ExceptionMapper<UnauthorizedException> { private val logger: Logger = Logger.getLogger(this.javaClass.simpleName) override fun toResponse(exception: UnauthorizedException): Response { logger.severe(exception.message) val message = exception.message val code = STATUS.statusCode val error = ErrorInfo(STATUS.statusCode, STATUS.name, message) return Response .status(code) .entity(error) .build() } companion object { private val STATUS = Response.Status.UNAUTHORIZED } }
方案三:failureHandler
@ApplicationScoped class UnauthorizedExceptionHandler { fun init(@Observes router: Router) { router.route().failureHandler { event -> if (event.failure() is UnauthorizedException) { event.response().end("CUSTOMIZED_RESPONSE") } else { event.next() } } } }
问题原因与解决办法
1. 异常类型不匹配
Quarkus安全模块(如JWT、OIDC认证)抛出的是io.quarkus.security.UnauthorizedException,而非JAX-RS标准的javax.ws.rs.core.UnauthorizedException。你的代码捕获的是后者,自然无法触发自定义逻辑。
解决:替换捕获的异常类型,以ServerExceptionMapper为例:
@ServerExceptionMapper @Priority(1) fun unauthorized(e: io.quarkus.security.UnauthorizedException): Response { val errorInfo = ErrorInfo( statusCode = Response.Status.UNAUTHORIZED.statusCode, errorCode = "UNAUTHORIZED", message = e.message ?: "用户未授权访问" ) return Response.status(Response.Status.UNAUTHORIZED) .entity(errorInfo) .build() }
2. 默认错误处理优先级更高
Quarkus自带的错误处理机制优先级可能高于自定义Mapper,导致逻辑被跳过。
解决:在application.properties中添加配置调整处理模式:
# 传统Resteasy使用 quarkus.resteasy.path-handler-legacy-mode=true # Resteasy Reactive使用 quarkus.resteasy-reactive.path-handler-legacy-mode=true
3. ExceptionMapper未被正确扫描
确保UnauthorizedErrorMapper类位于Quarkus自动扫描的包下,或在配置中指定扫描路径:
quarkus.package.jaxrs.paths=你的自定义包路径
4. ErrorInfo序列化问题
若自定义响应体未正确返回,检查ErrorInfo类是否添加JSON序列化注解(如Jackson的@Data、@JsonInclude),确保能正常序列化为JSON格式。
验证方法
在自定义处理逻辑中添加日志打印,确认是否被触发:
logger.info("自定义Unauthorized响应已执行")
内容的提问来源于stack exchange,提问作者Patrice Conil
相关产品推荐
相关产品推荐

