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
相关产品推荐
相关产品推荐

