第 4 章 主动验证


了解如何在 Quarkus 中管理主动身份验证,包括自定义设置和处理异常。获取各种应用程序场景的实用见解和策略。

主动验证在 Quarkus 中默认启用。它确保所有传入的请求都通过身份验证,即使目标页面不需要身份验证。因此,带有无效凭证的请求将被拒绝,即使目标页面是公共的。没有凭证的请求不会被拒绝,因为允许匿名请求。

只有在目标页面需要时才需要身份验证时,可以关闭此默认行为。要关闭主动身份验证,以便仅在目标页面需要时才进行身份验证,请按如下所示修改 application.properties 配置文件:

quarkus.http.auth.proactive=false
Copy to Clipboard Toggle word wrap

如果您关闭主动身份验证,身份验证过程仅在请求身份时运行。可以请求一个身份,因为需要需要用户进行身份验证的安全规则,或者因为需要对当前身份进行编程访问。

如果没有使用主动身份验证,访问 SecurityIdentity 是一个阻止操作。这是因为身份验证可能已经发生,访问 SecurityIdentity 可能需要调用外部系统,如数据库,这可能会阻止操作。对于阻止应用程序,这并不是一个问题。但是,如果您在被动应用程序中禁用了身份验证,则会失败,因为您无法阻止 I/O 线程的操作。要临时解决这个问题,您需要 @Inject 一个 io.quarkus.security.identity.CurrentIdentityAssociation 实例,并调用 Uni<SecurityIdentity> getDeferredIdentity (); 方法。然后,您可以订阅生成的 Uni,以便在身份验证完成后获得通知,且身份可用。

注意

您仍然可以从使用 @RolesAllowed 、@Authenticated、@Authenticated ,或具有相应配置授权检查的端点同时访问 Quarkus REST 中的 SecurityIdentity getIdentity () (以前为 RESTEasy Reactive)。如果路由响应是同步,则也对 Reactive 路由 也有效。

禁用主动身份验证后,如果未同步返回值的安全方法,则 CDI Bean 上使用 的标准安全注解 在 I/O 线程上无法正常工作。由于需要这些方法访问 SecurityIdentity,就会产生这个限制。

以下示例定义了 HelloResourceHelloService。任何对 /hello 的 GET 请求都在 I/O 线程上运行,并抛出 BlockingOperationNotAllowedException 异常。

修复示例的方法不止一种:

  • 通过注解带有 @Blockinghello 端点来切换到 worker 线程。
  • 使用被动或异步数据类型更改 sayHello 方法返回类型。
  • @RolesAllowed 注释移到端点。这可能是安全的方法之一,因为从端点方法访问 SecurityIdentity 并不是阻塞操作。
import jakarta.annotation.security.PermitAll;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import io.smallrye.mutiny.Uni;

@Path("/hello")
@PermitAll
public class HelloResource {

    @Inject
    HelloService helloService;

    @GET
    public Uni<String> hello() {
        return Uni.createFrom().item(helloService.sayHello());
    }

}
Copy to Clipboard Toggle word wrap
import jakarta.annotation.security.RolesAllowed;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class HelloService {

    @RolesAllowed("admin")
    public String sayHello() {
        return "Hello";
    }

}
Copy to Clipboard Toggle word wrap

4.1. 激活 CDI 请求上下文

您可能需要在身份验证和授权期间注入 @RequestScoped Bean。这是在 SecurityIdentity 增强过程中访问数据库的一个很好的例子,这在" 安全提示和 Tricks"指南的"安全身份自定义 "部分中描述。如果身份验证或授权失败并显示 jakarta.enterprise.context.ContextNotActiveException,则禁用主动身份验证通常是最佳解决方案。用户也可以使用 @ActivateRequestContext 注释激活 CDI 请求上下文。但是,一些 CDI Bean 可能未就绪。

此解决方案的一个例外是应用端点 使用配置 进行授权保护时的情况。有关更多信息,请参阅"Authorization of Web 端点"指南中的 Inject RequestScoped Bean into HttpSecurityPolicy 部分以了解更多信息。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat