如果未通过身份验证,Quarkus 会提供重定向 url
Quarkus provide redirect url if not authenticated
我正在建立一个网络ui,并决定通过 cookie 中的 jwt 获得授权。
我已经完成了最低限度的工作,但是当我将页面保留在角色后面时,该页面(可以预见)不会加载。与其不加载,我更希望能够告诉端点重定向到实际的登录页面。这可能吗?理想情况下,我将能够在端点上提供注释以说明“如果未经授权,请转到此处”。
我设置网络的代码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();
}
}
这取决于您希望如何处理安全和导航。
如果您使用声明式 RBAC(@RolesAllowed
),那么您只能通过 JAXRS ExceptionMapper 控制响应。您需要知道异常,即当用户无权访问所需资源时抛出的异常;例如,如果用户拥有有效令牌但不满足 @RolesAllowed
约束,那么它将是 io.quarkus.security.ForbiddenException
,如果他没有通过有效凭据,则 io.quarkus.security.UnauthorizedException
.
当您知道异常时,您可以定义您的 ExceptionMapper(确保您通过 @Priority
设置了正确的优先级,因为类路径上可能还有其他异常映射器,例如 Quarkus 在开发模式下提供的那些) .
实际的响应处理取决于客户端是什么:如果是浏览器,那么您可能想要 return 303
或 302
重定向响应 location
header 包含您的登录 URL 以便将原始请求重定向到登录。 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
所需的属性,如果不够,return 相应的 Response
例如return Response.seeOther("/login")
.
这应该可行,但如果您的客户端是一些 javascript 代码,执行 POST 请求,则可能会导致问题。一般来说,您最好从专用服务器为您的 UI 提供服务,使用 Quarkus 作为 API 端点提供程序,通过 HTTP/REST 在您的 UI 和 BE 之间进行通信。这样你就可以更好地控制行为。
我正在建立一个网络ui,并决定通过 cookie 中的 jwt 获得授权。
我已经完成了最低限度的工作,但是当我将页面保留在角色后面时,该页面(可以预见)不会加载。与其不加载,我更希望能够告诉端点重定向到实际的登录页面。这可能吗?理想情况下,我将能够在端点上提供注释以说明“如果未经授权,请转到此处”。
我设置网络的代码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();
}
}
这取决于您希望如何处理安全和导航。
如果您使用声明式 RBAC(@RolesAllowed
),那么您只能通过 JAXRS ExceptionMapper 控制响应。您需要知道异常,即当用户无权访问所需资源时抛出的异常;例如,如果用户拥有有效令牌但不满足 @RolesAllowed
约束,那么它将是 io.quarkus.security.ForbiddenException
,如果他没有通过有效凭据,则 io.quarkus.security.UnauthorizedException
.
当您知道异常时,您可以定义您的 ExceptionMapper(确保您通过 @Priority
设置了正确的优先级,因为类路径上可能还有其他异常映射器,例如 Quarkus 在开发模式下提供的那些) .
实际的响应处理取决于客户端是什么:如果是浏览器,那么您可能想要 return 303
或 302
重定向响应 location
header 包含您的登录 URL 以便将原始请求重定向到登录。 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
所需的属性,如果不够,return 相应的 Response
例如return Response.seeOther("/login")
.
这应该可行,但如果您的客户端是一些 javascript 代码,执行 POST 请求,则可能会导致问题。一般来说,您最好从专用服务器为您的 UI 提供服务,使用 Quarkus 作为 API 端点提供程序,通过 HTTP/REST 在您的 UI 和 BE 之间进行通信。这样你就可以更好地控制行为。