如果未通过身份验证,Quarkus 会提供重定向 url

Posted

技术标签:

【中文标题】如果未通过身份验证,Quarkus 会提供重定向 url【英文标题】:Quarkus provide redirect url if not authenticated 【发布时间】:2021-12-23 07:31:13 【问题描述】:

我正在构建一个 web ui,并决定通过 jwt 在 cookie 中获取身份验证。

我已经获得了最低限度的工作,但是当我将页面保留在角色后面时,页面(可以预见)不会加载。与其不加载,我更希望能够告诉端点重定向到实际的登录页面。这可能吗?理想情况下,我可以在端点上提供注释说“如果未经过身份验证,请转到此处”。

我设置 Web ui 端点的代码:

@Traced
@Slf4j
@Path("/")
@Tags(@Tag(name = "UI"))
@RequestScoped
@Produces(MediaType.TEXT_html)
public class Index extends UiProvider 

    @Inject
    @Location("webui/pages/index")
    Template index;
    @Inject
    @Location("webui/pages/overview")
    Template overview;

    @Inject
    UserService userService;

    @Inject
    JsonWebToken jwt;

    @GET
    @PermitAll
    @Produces(MediaType.TEXT_HTML)
    public TemplateInstance index(
            @Context SecurityContext securityContext
    ) 
        logRequestContext(jwt, securityContext);
        return index.instance();
    

    @GET
    @Path("overview")
    @RolesAllowed("user")
    @Produces(MediaType.TEXT_HTML)
    public TemplateInstance overview(
            @Context SecurityContext securityContext
    ) 
        logRequestContext(jwt, securityContext);
        return overview.instance();
    

【问题讨论】:

【参考方案1】:

这取决于您希望如何处理安全性和导航。 如果您使用声明性 RBAC(@RolesAllowed),则只能通过 JAXRS ExceptionMapper 控制响应。您需要知道当用户无权访问所需资源时引发的异常;例如,如果用户拥有有效令牌但不满足@RolesAllowed 约束,则为io.quarkus.security.ForbiddenException,如果他未通过有效凭据,则为io.quarkus.security.UnauthorizedException

当您知道异常时,您可以定义您的 ExceptionMapper(确保通过 @Priority 设置正确的优先级,因为类路径上可能还有其他异常映射器,例如 Quarkus 在开发模式下提供的那些)。

实际的响应处理取决于客户端是什么:如果是浏览器,那么您可能希望返回 303302 重定向响应,并带有包含您的登录 URL 的 location 标头,以便原始请求是重定向到登录。 UnauthorizedException 的示例:

import io.quarkus.security.UnauthorizedException;

import javax.annotation.Priority;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider//register it as jaxrs provider
@Priority(1)//lower number-higher prio
//exception mappers are selected on best match for the exception class
//so make sure you find the particular exception you want to map
public class MyUnauthorizedExceptionMapper implements ExceptionMapper<UnauthorizedException>  
    @Context//you can inject JAXRS contextual resources here
    UriInfo crc;

    @Override
    public Response toResponse(UnauthorizedException exception) 
        System.out.println("User not authorized to access: " + crc.getRequestUri());
        return Response //seeOther = 303 redirect
                .seeOther(UriBuilder.fromUri("/someLogin")
                        //common pattern is to pass the original URL as param,
                        //so that after successful login, you redirect user back where he wanted
                        .queryParam("returnUrl", crc.getRequestUri())
                        .build())//build the URL where you want to redirect
                .entity("Not authorized")//entity is not required
                .build();
    

其他选项是,您在端点内以编程方式处理身份验证,检查Principal 或当前JWTToken 以获取所需属性,如果不够,则返回相应的Response,例如return Response.seeOther("/login").

这应该可行,但如果您的客户端是一些 javascript 代码,执行 POST 请求,则可能会导致问题。一般来说,您最好从专用服务器提供您的 UI,使用 Quarkus 作为 API 端点提供者,通过 HTTP/REST 在您的 UI 和 BE 之间进行通信。这样您就可以更好地控制行为。

【讨论】:

这就是我最终实现的,希望可能有一种更简单的方法,比如注释,但这有效。谢谢!

以上是关于如果未通过身份验证,Quarkus 会提供重定向 url的主要内容,如果未能解决你的问题,请参考以下文章

如果未通过身份验证,则颤振 Web 重定向用户

Flask - 如果当前用户未通过身份验证,如何重定向到登录页面?

如果用户未使用中间件进行身份验证,Laravel 5.4 将重定向到特定页面

仅当未使用 @azure/msal-react 进行身份验证时才重定向 onLoad

React - 未通过身份验证时重定向到登录页面

Laravel - 用户未通过身份验证时如何重定向到所需页面