Quarkus未认证场景下如何配置端点跳转指定登录URL?
解决方案
该需求完全可实现,以下是基于你当前JAX-RS(从代码特征判断为Quarkus+RESTEasy架构)的最简实现方案:
实现逻辑
你当前使用的@RolesAllowed是JAX-RS标准RBAC注解,未认证用户访问受保护端点时,框架会默认抛出NotAuthorizedException并返回401响应,我们只需通过自定义注解+全局异常映射器的组合就能实现按端点配置跳转地址的需求。
步骤1:自定义跳转注解
首先定义一个用来标注跳转地址的注解:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LoginRedirect { // 配置跳转地址,默认是/login,可根据业务修改 String value() default "/login"; }
步骤2:实现全局异常映射器
捕获认证失败异常,读取注解配置的跳转地址,返回302跳转响应:
import org.jboss.resteasy.spi.NotAuthorizedException; import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @Provider public class AuthFailedRedirectMapper implements ExceptionMapper<NotAuthorizedException> { @Context ResourceInfo resourceInfo; @Context javax.ws.rs.core.UriInfo uriInfo; @Context javax.ws.rs.core.HttpHeaders httpHeaders; @Override public Response toResponse(NotAuthorizedException exception) { // 仅对HTML页面请求做跳转,不影响JSON接口的401响应 if (httpHeaders.getAcceptableMediaTypes().contains(javax.ws.rs.core.MediaType.TEXT_HTML_TYPE)) { // 读取目标方法上的跳转注解 LoginRedirect redirectAnnotation = resourceInfo.getResourceMethod().getAnnotation(LoginRedirect.class); if (redirectAnnotation != null) { // 拼接当前请求地址作为登录后回跳参数,可按需保留 String redirectUrl = redirectAnnotation.value() + "?redirect_url=" + URLEncoder.encode(uriInfo.getRequestUri().toString(), StandardCharsets.UTF_8); return Response.seeOther(URI.create(redirectUrl)).build(); } } // 非页面请求/无跳转注解时走默认401响应 return Response.status(Response.Status.UNAUTHORIZED).build(); } }
步骤3:给需要跳转的端点加注解
修改你现有的端点代码,给受保护的页面接口加@LoginRedirect注解即可:
@GET @Path("overview") @RolesAllowed("user") @Produces(MediaType.TEXT_HTML) @LoginRedirect("/user/login") // 可自定义跳转地址,不填则用注解默认的/login public TemplateInstance overview( @Context SecurityContext securityContext ) { logRequestContext(jwt, securityContext); return overview.instance(); }
可选扩展
如果需要对已登录但角色不匹配的情况跳转到无权限提示页,可新增一个@ForbiddenRedirect注解,再新增一个ExceptionMapper<ForbiddenException>的实现类,逻辑和上面的认证异常映射器完全一致即可。
内容的提问来源于stack exchange,提问作者Snappawapa
相关产品推荐
相关产品推荐

