4.2. 自定义身份验证异常响应
您可以使用 Jakarta REST ExceptionMapper 来捕获 Quarkus 安全身份验证异常,如 io.quarkus.security.AuthenticationFailedException。例如:
package io.quarkus.it.keycloak;
import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import io.quarkus.security.AuthenticationFailedException;
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFailedExceptionMapper implements ExceptionMapper<AuthenticationFailedException> {
@Context
UriInfo uriInfo;
@Override
public Response toResponse(AuthenticationFailedException exception) {
return Response.status(401).header("WWW-Authenticate", "Basic realm=\"Quarkus\"").build();
}
}
Important
有些 HTTP 身份验证机制必须处理身份验证异常本身,才能创建正确的身份验证问题。例如: io.quarkus.oidc.runtime.CodeAuthenticationMechanism,它管理 OpenID Connect (OIDC)授权代码流身份验证,必须构建正确的重定向 URL 并设置状态 Cookie。因此,避免使用自定义异常映射器自定义由此类机制引发的身份验证异常。相反,一种更安全的方法是确保启用主动身份验证并使用 Vert.x HTTP 路由失败处理程序。这是因为事件发送到带有正确响应状态和标头的处理程序。然后,您必须只自定义响应,例如:
package io.quarkus.it.keycloak;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import io.quarkus.security.AuthenticationFailedException;
import io.vertx.core.Handler;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
@ApplicationScoped
public class AuthenticationFailedExceptionHandler {
public void init(@Observes Router router) {
router.route().failureHandler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
if (event.failure() instanceof AuthenticationFailedException) {
event.response().end("CUSTOMIZED_RESPONSE");
} else {
event.next();
}
}
});
}
}