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

如何在quarkus-oidc中自定义403、401错误状态码的响应体

Quarkus OIDC 自定义401/403响应体实现方案

Quarkus OIDC的认证授权异常触发时机早于普通JAX-RS请求链路,因此不能直接复用Spring Boot的异常处理逻辑,可通过以下两种方案实现自定义响应:

方案1:自定义Security异常Mapper(推荐,兼容性最强)

该方案适配所有Quarkus安全模块抛出的认证授权异常,不需要修改底层HTTP逻辑:

  • 首先确认项目依赖已引入quarkus-resteasy-reactive或quarkus-resteasy扩展
  • 分别创建401、403对应的异常Mapper,添加@Priority(1)注解覆盖Quarkus默认的异常处理实现

401(未认证)响应自定义代码示例

import io.quarkus.security.AuthenticationFailedException;
import jakarta.annotation.Priority;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

@Provider
@Priority(1)
public class CustomAuthFailedMapper implements ExceptionMapper<AuthenticationFailedException> {

    @Override
    public Response toResponse(AuthenticationFailedException exception) {
        // 自定义响应体结构,可根据业务需求调整字段
        var errorResp = new CustomError();
        errorResp.setCode(401);
        errorResp.setMsg("无效的访问凭证,请重新登录");
        return Response.status(Response.Status.UNAUTHORIZED)
                .entity(errorResp)
                .build();
    }
}

403(未授权)响应自定义代码示例

import io.quarkus.security.ForbiddenException;
import jakarta.annotation.Priority;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

@Provider
@Priority(1)
public class CustomForbiddenMapper implements ExceptionMapper<ForbiddenException> {

    @Override
    public Response toResponse(ForbiddenException exception) {
        var errorResp = new CustomError();
        errorResp.setCode(403);
        errorResp.setMsg("当前账号无权限访问该资源");
        return Response.status(Response.Status.FORBIDDEN)
                .entity(errorResp)
                .build();
    }
}
  • 在application.properties中添加配置,禁用OIDC默认的登录挑战头,避免浏览器自动弹出登录框:
quarkus.oidc.authentication.challenge-enabled=false

方案2:Vert.x全局错误处理器(覆盖所有HTTP层异常)

如果方案1无法覆盖token解析失败、OIDC服务连接异常等边缘场景,可以直接注册Vert.x路由器的全局错误处理器:

import io.quarkus.vertx.http.RouterCustomizer;
import io.vertx.core.json.Json;
import io.vertx.ext.web.Router;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GlobalHttpErrorHandler implements RouterCustomizer {

    @Override
    public void accept(Router router) {
        // 处理401异常
        router.errorHandler(401, ctx -> {
            var resp = Json.of("code", 401, "msg", "访问未授权");
            ctx.response()
                    .setStatusCode(401)
                    .putHeader("Content-Type", "application/json")
                    .end(resp.encode());
        });
        // 处理403异常
        router.errorHandler(403, ctx -> {
            var resp = Json.of("code", 403, "msg", "无访问权限");
            ctx.response()
                    .setStatusCode(403)
                    .putHeader("Content-Type", "application/json")
                    .end(resp.encode());
        });
    }
}

注意事项

  • 不要使用通用ExceptionMapper<RuntimeException>捕获这两类异常,默认优先级低于Quarkus安全模块内置的Mapper,会出现不生效问题
  • 如果项目同时使用了多个安全扩展,优先选择方案1,不会影响其他安全逻辑的正常运行
  • 自定义响应需要返回JSON格式时,确保项目已引入quarkus-resteasy-reactive-jackson或对应的JSON序列化依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:24:03