如果未通过身份验证,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 在开发模式下提供的那些)。
实际的响应处理取决于客户端是什么:如果是浏览器,那么您可能希望返回 303
或 302
重定向响应,并带有包含您的登录 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的主要内容,如果未能解决你的问题,请参考以下文章
Flask - 如果当前用户未通过身份验证,如何重定向到登录页面?
如果用户未使用中间件进行身份验证,Laravel 5.4 将重定向到特定页面