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

Quarkus使用SmallRye JWT时自定义UNAUTHORIZE响应JSON体

可以实现,以下是具体方案

你不需要修改SmallRye JWT的默认认证机制,通过自定义JAX-RS ExceptionMapper就能捕获认证相关异常并返回自定义JSON响应体,步骤如下:

1. 定义错误响应DTO

创建一个用于封装错误信息的实体类,确保它能被序列化为JSON:

public class ErrorResponse {
    private int statusCode;
    private String errorType;
    private String message;
    private long timestamp;

    public ErrorResponse(int statusCode, String errorType, String message) {
        this.statusCode = statusCode;
        this.errorType = errorType;
        this.message = message;
        this.timestamp = System.currentTimeMillis();
    }

    // 生成所有字段的getter/setter方法
}

2. 实现异常映射器(ExceptionMapper)

针对Quarkus安全模块和SmallRye JWT抛出的各类认证异常,分别编写映射器,将异常转为自定义JSON响应:

处理JWT解析失败异常

import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import io.smallrye.jwt.auth.principal.ParseException;

@Provider
public class JwtParseExceptionMapper implements ExceptionMapper<ParseException> {
    @Override
    public Response toResponse(ParseException exception) {
        ErrorResponse error = new ErrorResponse(
                Response.Status.UNAUTHORIZED.getStatusCode(),
                "INVALID_JWT",
                "JWT令牌解析失败: " + exception.getMessage()
        );
        return Response.status(Response.Status.UNAUTHORIZED)
                .entity(error)
                .type(MediaType.APPLICATION_JSON)
                .build();
    }
}

处理认证失败异常

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

@Provider
public class AuthFailedExceptionMapper implements ExceptionMapper<AuthenticationFailedException> {
    @Override
    public Response toResponse(AuthenticationFailedException exception) {
        ErrorResponse error = new ErrorResponse(
                Response.Status.UNAUTHORIZED.getStatusCode(),
                "AUTH_FAILED",
                "身份验证失败: " + exception.getMessage()
        );
        return Response.status(Response.Status.UNAUTHORIZED)
                .entity(error)
                .type(MediaType.APPLICATION_JSON)
                .build();
    }
}

处理缺少令牌的未授权异常

import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import jakarta.ws.rs.NotAuthorizedException;

@Provider
public class NotAuthorizedExceptionMapper implements ExceptionMapper<NotAuthorizedException> {
    @Override
    public Response toResponse(NotAuthorizedException exception) {
        ErrorResponse error = new ErrorResponse(
                Response.Status.UNAUTHORIZED.getStatusCode(),
                MISSING_TOKEN",
                "请求缺少有效JWT授权令牌"
        );
        return Response.status(Response.Status.UNAUTHORIZED)
                .entity(error)
                .type(MediaType.APPLICATION_JSON)
                .build();
    }
}

3. 验证效果

启动Quarkus应用后,当出现JWT缺失、解析失败或认证失败时,接口会返回如下格式的JSON响应:

{
    "statusCode": 401,
    "errorType": "INVALID_JWT",
    "message": "JWT令牌解析失败: Signature verification failed",
    "timestamp": 1725000000000
}

注意事项

  • 所有@Provider注解的映射器会被Quarkus自动扫描并注册,无需额外配置
  • 即使你有自定义的AuthenticationMechanism代码,这些映射器依然会优先处理异常
  • 可根据业务需求扩展更多异常类型的映射,比如权限不足的403异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:15:40