2.2. 内置身份验证机制


Quarkus Security 提供以下内置身份验证支持:

2.2.1. 基本身份验证(Basic authentication)

您可以使用内置 HTTP 基本身份验证机制保护 Quarkus 应用程序端点。如需更多信息,请参阅以下文档:

2.2.2. 基于表单的身份验证

Quarkus 提供基于表单的身份验证,它们的工作方式类似于传统的 Servlet 形式的身份验证。与传统的形式身份验证不同,经过身份验证的用户不会存储在 HTTP 会话中,因为 Quarkus 不支持集群的 HTTP 会话。相反,身份验证信息存储在加密的 Cookie 中,可由共享同一加密密钥的所有群集成员读取。

要应用加密,请添加 quarkus.http.auth.session.encryption-key 属性,并确保您设置的值至少为 16 个字符。加密密钥使用 SHA-256 进行哈希处理。生成的摘要用作 Cookie 值的 AES-256 加密的密钥。Cookie 包含作为加密值的一部分的到期时间,因此集群中的所有节点都必须同步其时钟。在一分钟的间隔内,如果会话正在使用,则会使用更新的到期时间生成新的 Cookie。

要开始使用表单身份验证,您应该有类似的设置,如 启用基本身份验证和属性 quarkus.http.auth.form.enabled 所述,必须设置为 true

带有表单验证的简单 application.properties 类似如下:

quarkus.http.auth.form.enabled=true

quarkus.http.auth.form.login-page=login.html
quarkus.http.auth.form.landing-page=hello
quarkus.http.auth.form.error-page=

# Define testing user
quarkus.security.users.embedded.enabled=true
quarkus.security.users.embedded.plain-text=true
quarkus.security.users.embedded.users.alice=alice
quarkus.security.users.embedded.roles.alice=user
Copy to Clipboard Toggle word wrap
重要

在 application.properties 文件中配置用户名、secret 和角色只适用于测试场景。对于保护生产应用,使用数据库或 LDAP 存储此信息至关重要。如需更多信息,您可以查看 带有 Jakarta Persistence 的 Quarkus 安全性,或其他 启用基本身份验证 中所述。

应用程序登录页面将包含类似如下的 HTML 表单:

<form action="/j_security_check" method="post">
    <label>Username</label>
    <input type="text" placeholder="Username" name="j_username" required>
    <label>Password</label>
    <input type="password" placeholder="Password" name="j_password" required>
    <button type="submit">Login</button>
</form>
Copy to Clipboard Toggle word wrap

使用单页应用程序(SPA),您通常希望通过删除默认页面路径来避免重定向,如下例所示:

# do not redirect, respond with HTTP 200 OK
quarkus.http.auth.form.landing-page=

# do not redirect, respond with HTTP 401 Unauthorized
quarkus.http.auth.form.login-page=
quarkus.http.auth.form.error-page=

# HttpOnly must be false if you want to log out on the client; it can be true if logging out from the server
quarkus.http.auth.form.http-only-cookie=false
Copy to Clipboard Toggle word wrap

现在,您已为 SPA 禁用了重定向,您必须以编程方式从客户端登录并注销。以下是登录 j_security_check 端点的 JavaScript 方法示例,并通过销毁 Cookie 来注销应用。

const login = () => {
    // Create an object to represent the form data
    const formData = new URLSearchParams();
    formData.append("j_username", username);
    formData.append("j_password", password);

    // Make an HTTP POST request using fetch against j_security_check endpoint
    fetch("j_security_check", {
        method: "POST",
        body: formData,
        headers: {
            "Content-Type": "application/x-www-form-urlencoded",
        },
    })
    .then((response) => {
        if (response.status === 200) {
            // Authentication was successful
            console.log("Authentication successful");
        } else {
            // Authentication failed
            console.error("Invalid credentials");
        }
    })
    .catch((error) => {
        console.error(error);
    });
};
Copy to Clipboard Toggle word wrap

要从客户端注销 SPA,cookie 必须设为 quarkus.http.auth.form.http-only-cookie=false,以便您可以销毁 Cookie,并可能重定向到您的主页。

const logout= () => {
    // delete the credential cookie, essentially killing the session
    const removeCookie = `quarkus-credential=; Max-Age=0;path=/`;
    document.cookie = removeCookie;

    // perform post-logout actions here, such as redirecting back to your login page
};
Copy to Clipboard Toggle word wrap

要从服务器注销 SPA,cookie 可以设置为 quarkus.http.auth.form.http-only-cookie=true,并使用此示例代码销毁 Cookie。

import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.security.FormAuthenticationMechanism;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.POST;

@Inject
SecurityIdentity identity;

@POST
public Response logout() {
    if (identity.isAnonymous()) {
        throw new UnauthorizedException("Not authenticated");
    }
    FormAuthenticationMechanism.logout(identity); 
1

    return Response.noContent().build();
}
Copy to Clipboard Toggle word wrap
1
通过删除会话 Cookie 来执行注销。

2.2.2.1. 基于表单的身份验证配置参考

以下属性可用于配置基于表单的身份验证:

build 时修复的 :在构建时修复的配置属性 - 所有其他配置属性在运行时可覆盖

Expand

配置属性

Type

default

quarkus.http.auth.permission."permissions".enabled

确定是否启用整个权限集。

默认情况下,如果定义了权限集,则会启用它。

环境变量: QUARKUS_HTTP_AUTH_PERMISSION__PERMISSIONS__ENABLED

布尔值

 

quarkus.http.auth.permission."permissions".policy

此权限集链接到的 HTTP 策略。

有三个内置策略:allow、deny 和 authenticated。可以定义基于角色的策略,扩展可以添加自己的策略。

环境变量: QUARKUS_HTTP_AUTH_PERMISSION__PERMISSIONS__POLICY

string

所需的 HEKETI Required

quarkus.http.auth.permission."permissions".methods

此权限集的方法应用到。如果没有设置,则适用于所有方法。

请注意,如果请求与任何权限集中的任何路径匹配,但由于未列出方法,则请求将被拒绝。

方法特定权限优先于未设置任何方法的匹配项。

这意味着,如果 Quarkus 配置为允许 GET 和 POST 请求到 /admin,且没有将其他权限配置为 /admin 将被拒绝。

环境变量: QUARKUS_HTTP_AUTH_PERMISSION__PERMISSIONS__METHODS

字符串列表

 

quarkus.http.auth.permission."permissions".paths

此权限检查应用到的路径。如果路径以 86] 结尾,则这被视为路径前缀,否则它将被视为完全匹配。

匹配会以长度为基础完成,因此最具体的路径匹配具有优先权。

如果多个权限集与同一路径匹配,那么显式方法匹配优先于设置方法,否则应用最严格的权限。

环境变量: QUARKUS_HTTP_AUTH_PERMISSION__PERMISSIONS__PATHS

字符串列表

 

quarkus.http.auth.permission."permissions".auth-mechanism

必须用来验证用户身份的路径特定身份验证机制。它需要匹配 io.quarkus.vertx.http.runtime.security.HttpCredentialTransport 身份验证方案,如 'basic'、'bearer'、'form' 等。

环境变量: QUARKUS_HTTP_AUTH_PERMISSION__PERMISSIONS__AUTH_MECHANISM

string

 

quarkus.http.auth.permission."permissions".shared

表示除了具有获奖路径的策略外,此策略还始终适用于匹配的路径。避免创建多个共享策略,以最大程度降低性能影响。

环境变量: QUARKUS_HTTP_AUTH_PERMISSION__PERMISSIONS__SHARED

布尔值

false

quarkus.http.auth.permission."permissions".applies-to

权限检查是否应该应用到所有匹配路径,还是专用于 Jakarta REST 资源的路径。

环境变量: QUARKUS_HTTP_AUTH_PERMISSION__PERMISSIONS__APPLIES_TO

All :适用于所有匹配路径。

jaxrs: Declares,权限检查必须仅应用于 Jakarta REST 请求路径。使用这个选项,延迟权限检查是否使用匹配的 Jakarta REST 端点上的注解选择验证机制。如果使用以下 REST 端点注解,则必须设置这个选项:- io.quarkus.oidc.Tenant 注解,它选择带有租户标识符的 OIDC 身份验证机制 - io.quarkus.vertx.http.runtime.security.annotation.BasicAuthentication,它选择 Basic 身份验证机制 - io.quarkus.vertx.http.runtime.security.annotation.FormAuthentication 选择基于 Form 的身份验证机制 - io.quarkus.vertx.http.runtime.security.annotation.MTLS Authentication,它选择 mTLS 身份验证机制 - io.quarkus.security.webauthn.WebAuth n 选择 WebAuth 身份验证机制 - io.quarkus.oidc.BearerToken Authentication,它选择 OpenID Connect Bearer 令牌身份验证机制 - - io.quarkus.oidc.Authorization CodeFlow,它选择 OpenID Connect Code 身份验证机制

all

quarkus.http.auth.policy."role-policy".roles-allowed

允许访问此策略保护的资源的角色。默认情况下,任何经过身份验证的用户都允许访问。

环境变量: QUARKUS_HTTP_AUTH_POLICY_ROLE_POLICY__ROLES_ALLOWED

字符串列表

**

quarkus.http.auth.policy."role-policy".roles."role-name"

根据 SecurityIdentity 已存在的角色,为 SecurityIdentity 添加授予的角色。例如,Quarkus OIDC 扩展可以映射来自验证的 JWT 访问令牌的角色,您可能希望将它们重新映射到部署特定的角色。

环境变量: QUARKUS_HTTP_AUTH_POLICY__ROLE_POLICY__ROLES__ROLE_NAME_

Map<String,List<String>>

 

quarkus.http.auth.policy."role-policy".permissions."role-name"

如果成功应用此策略,则授予 SecurityIdentity 的权限(策略允许请求继续),并且经过身份验证的请求具有必要的角色。例如,您可以通过设置 quarkus.http.auth.policy.role-policy1.permissions. admin =perm1:action1,perm1: action2 配置属性 将每个m1 的权限映射为 role admin授予的权限用于通过 @PermissionsAllowed 注释进行授权。

环境变量: QUARKUS_HTTP_AUTH_POLICY__ROLE_POLICY__PERMISSIONS__ROLE_NAME_

Map<String,List<String>>

 

quarkus.http.auth.policy."role-policy".permission-class

此策略授予的权限将通过此配置属性指定的 java.security.Permission 实施来创建。权限类必须声明一个接受权限名称(String )或权限名称和操作(字符串、字符串[])的构造器。如果您以原生模式运行应用程序,则必须注册权限类,以反映其是否运行您的应用程序。

环境变量: QUARKUS_HTTP_AUTH_POLICY__ROLE_POLICY__PERMISSION_CLASS

string

io.quarkus.security.StringPermission

quarkus.http.auth.roles-mapping."role-name"

SecurityIdentity 角色映射到部署特定的角色,并将匹配的角色添加到 SecurityIdentity

例如,如果 SecurityIdentity 具有用户角色,并且端点使用 'UserRole' 角色进行保护,则使用此属性将用户角色映射到 UserRole 角色,并且具有 SecurityIdentity 角色,并且具有 user UserRole 角色。

环境变量: QUARKUS_HTTP_AUTH_ROLES_MAPPING__ROLE_NAME_

Map<String,List<String>>

 

quarkus.http.auth.certificate-role-attribute

客户端证书属性,其值将根据证书属性文件中指定的角色映射映射到"安全Identity"角色。属性必须是 Relative Distinguished Names (RDN)或 Subject Alternative Names (SAN)之一。默认情况下,通用名称(CN)属性值用于角色映射。支持的值有:

  • rdn type - Distinguished Name 字段。例如 'CN' 代表 Common Name 字段。目前不支持 Multivalued RNDs 和相同属性的多个实例。
  • 'SAN_RFC822' - Subject Alternative Name field RFC 822 Name.
  • 'SAN_URI' - Subject Alternative Name field Uniform Resource Identifier (URI)。
  • 'SAN_ANY' - Subject Alternative Name field Other Name.请注意,只支持 UTF8 标识符映射的简单情况。例如,您可以将 'other-identifier' 映射到 SecurityIdentity 角色。如果您使用 'openssl' 工具,则支持其他名称定义类似如下: subjectAltName=otherName:1.2.3.4;UTF8:other-identifier

环境变量: QUARKUS_HTTP_AUTH_CERTIFICATE_ROLE_ATTRIBUTE

string

CN

quarkus.http.auth.certificate-role-properties

包含客户端证书属性值到角色映射的属性文件。只有在使用 quarkus.http.ssl.client-auth=requiredquarkus.http.ssl.client-auth=request 启用 mTLS 身份验证机制时,才使用它。

属性文件预期具有 CN_VALUE=role1,role,…​,roleN 格式,并使用 UTF-8 进行编码。

环境变量: QUARKUS_HTTP_AUTH_CERTIFICATE_ROLE_PROPERTIES

path

 

quarkus.http.auth.realm

身份验证域

环境变量: QUARKUS_HTTP_AUTH_REALM

string

 

quarkus.http.auth.form.login-page

登录页面。可以通过设置 quarkus.http.auth.form.login-page= 来禁用重定向到登录页面。

环境变量: QUARKUS_HTTP_AUTH_FORM_LOGIN_PAGE

string

/login.html

quarkus.http.auth.form.username-parameter

用户名字段名称。

环境变量: QUARKUS_HTTP_AUTH_FORM_USERNAME_PARAMETER

string

j_username

quarkus.http.auth.form.password-parameter

密码字段名称。

环境变量: QUARKUS_HTTP_AUTH_FORM_PASSWORD_PARAMETER

string

j_password

quarkus.http.auth.form.error-page

错误页面。可以通过设置 quarkus.http.auth.form.error-page= 来禁用重定向到错误页面。

环境变量: QUARKUS_HTTP_AUTH_FORM_ERROR_PAGE

string

/error.html

quarkus.http.auth.form.landing-page

如果没有保存的页面要重定向到,则要重定向到的登录页面。可以通过设置 quarkus.http.auth.form.landing-page= 来禁用到登录页面。

环境变量: QUARKUS_HTTP_AUTH_FORM_LANDING_PAGE

string

/index.html

quarkus.http.auth.form.location-cookie

选项控制用于将用户重新定向到他们要访问的位置的 Cookie 名称。

环境变量: QUARKUS_HTTP_AUTH_FORM_LOCATION_COOKIE

string

quarkus-redirect-location

quarkus.http.auth.form.timeout

不活跃(空闲)超时

当达到不活跃超时时,cookie 不会更新,并会强制使用新的登录。

环境变量: QUARKUS_HTTP_AUTH_FORM_TIMEOUT

持续时间 5-4 Duration 格式

PT30M

quarkus.http.auth.form.new-cookie-interval

Cookie 在新的 Cookie 被更新超时替代之前如何获得,也称为"renewal-timeout"。

请注意,较小的值会导致服务器负载稍多(因为新加密的 Cookie 将更频繁生成);但是,较大的值会影响不活动超时,因为在生成 Cookie 时设置了超时。

例如,如果这设为 10 分钟,并且不活跃超时为 30m,如果用户的最后一个请求为 9m,则实际超时将在最后一次请求后发生 21m,因为仅在生成新 Cookie 时超时才会刷新。

也就是说,在服务器端不会跟踪超时;时间戳采用 Cookie 本身进行编码和加密,并通过每个请求进行解密和解析。

环境变量: QUARKUS_HTTP_AUTH_FORM_NEW_COOKIE_INTERVAL

持续时间 5-4 Duration 格式

PT1M

quarkus.http.auth.form.cookie-name

用于存储持久会话的 Cookie

环境变量: QUARKUS_HTTP_AUTH_FORM_COOKIE_NAME

string

quarkus-credential

quarkus.http.auth.form.cookie-path

会话和位置 Cookie 的 Cookie 路径。

环境变量: QUARKUS_HTTP_AUTH_FORM_COOKIE_PATH

string

/

quarkus.http.auth.form.cookie-domain

Cookie 域参数值(如果设置了)将用于会话和位置 Cookie。

环境变量: QUARKUS_HTTP_AUTH_FORM_COOKIE_DOMAIN

string

 

quarkus.http.auth.form.http-only-cookie

设置 HttpOnly 属性,以防止通过 JavaScript 访问 Cookie。

环境变量: QUARKUS_HTTP_AUTH_FORM_HTTP_ONLY_COOKIE

布尔值

false

quarkus.http.auth.form.cookie-same-site

会话和位置 Cookie 的 SameSite 属性。

环境变量: QUARKUS_HTTP_AUTH_FORM_COOKIE_SAME_SITE

strict,lax,none

strict

quarkus.http.auth.form.cookie-max-age

会话 Cookie 的 max-Age 属性。这是浏览器将保留 Cookie 的时间。

默认值为空,这意味着 Cookie 将保留,直到浏览器关闭为止。

环境变量: QUARKUS_HTTP_AUTH_FORM_COOKIE_MAX_AGE

持续时间 5-4 Duration 格式

 

quarkus.http.auth.form.post-location

后位置。

环境变量: QUARKUS_HTTP_AUTH_FORM_POST_LOCATION

string

/j_security_check

quarkus.http.auth.inclusive

要求所有注册的 HTTP 身份验证机制都必须尝试验证请求凭据。

默认情况下,当 inclusive-mode 严格时,每个注册的身份验证机制都必须生成 SecurityIdentity,否则,生成身份的多个机制可能小于注册机制的总数。

所有生成的安全身份都可以使用以下工具的方法检索:

`io.quarkus.vertx.http.runtime.security.HttpSecurityUtils++#++getSecurityIdentities(io.quarkus.security.identity.SecurityIdentity)`
Copy to Clipboard Toggle word wrap

注入的 SecurityIdentity 代表一个由第一个包含身份验证机制生成的身份。当需要 mTLS 身份验证时,mTLS 机制始终是第一个机制,因为它的优先级会在包含验证时提升。

此属性默认为 false,这意味着当创建第一个 SecurityIdentity 时,身份验证过程会马上完成。

如果启用了特定于路径的身份验证,则此属性将被忽略。

环境变量: QUARKUS_HTTP_AUTH_INCLUSIVE

布尔值

false

quarkus.http.auth.inclusive-mode

包含的身份验证模式。

环境变量: QUARKUS_HTTP_AUTH_INCLUSIVE_MODE

lax: 如果至少有一个注册的 HTTP 身份验证机制创建了身份,则身份验证会成功。

严格 :如果所有注册的 HTTP 身份验证机制都创建身份,则身份验证成功。通常,当凭证通过 mTLS 执行时,包含的身份验证应该处于严格的模式,当 mTLS 和另一个身份验证(如 OIDC bearer 令牌身份验证)时,必须成功。在这种情况下,由第一个机制 mTLS 创建的 SecurityIdentity 可以注入,其他机制创建的身份将在 SecurityIdentity 上提供。

strict

关于 Duration 格式

要写入持续时间值,请使用标准 java.time.Duration 格式。如需更多信息,请参阅 Duration#parse ()Java API 文档

您还可以使用简化的格式,从数字开始:

  • 如果值只是一个数字,它代表时间(以秒为单位)。
  • 如果值为数字,后跟 ms,代表时间(毫秒)。

在其他情况下,简化的格式被转换为 java.time.Duration 格式以进行解析:

  • 如果该值是一个数字,后跟 hms,则前缀为 PT
  • 如果值为数字,后跟 d,则会以 P 为前缀。

2.2.2.2. 以编程方式设置基于表单的身份验证

除了 基于 Form 的身份验证配置参考部分中列出的配置 属性外,Quarkus 在运行时支持程序设置,如下例所示:

package org.acme.http.security;

import io.quarkus.vertx.http.security.Form;
import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;

public class FormConfiguration {

    void configure(@Observes HttpSecurity httpSecurity) {   
1

        httpSecurity.mechanism(Form.builder()
                .httpOnlyCookie()
                .loginPage("/my-login.html")
                .errorPage("/my-error.html")
                .build());
    }

}
Copy to Clipboard Toggle word wrap
1
观察 io.quarkus.vertx.http.security.HttpSecurity CDI 事件,并以编程方式配置 Form 身份验证机制。

2.2.3. 双向 TLS 身份验证

Quarkus 提供 mutual TLS (mTLS)身份验证,以便您可以根据其 X.509 证书验证用户。

要使用此验证方法,您必须首先为应用程序启用 SSL/TLS。如需更多信息,请参阅 Quarkus "HTTP 参考" 指南中的支持使用 SSL/TLS 的安全连接 部分。

在应用程序接受安全连接后,下一步是使用保存应用程序信任的所有证书的 quarkus.http.ssl.certificate.trust-store-file 属性配置 quarkus.http.ssl.certificate.trust-store-file 属性。此文件还包含有关当客户端(如浏览器或其他服务)如何请求证书的信息,请尝试访问受保护的资源之一。

因为 JKS 不再是 Quarkus 中的默认密钥存储和信任存储格式,因此框架会根据文件扩展名进行 educated guess:

  • .pem.crt.key 显示为 PEM 证书和密钥。
  • .jks.keystore、和 .truststore 显示为 JKS 密钥存储和信任存储。
  • .p12.pkcs12.pfx 显示为 PKCS12 密钥存储和信任存储。

如果您的文件没有使用其中一个扩展,则必须使用以下属性设置格式:

quarkus.http.ssl.certificate.key-store-file-type=JKS  # or P12 or PEM
quarkus.http.ssl.certificate.trust-store-file-type=JKS  # or P12 or PEM
Copy to Clipboard Toggle word wrap

JKS 变得不常使用。从 Java 9 开始,Java 的默认密钥存储格式是 PKCS12。JKS 和 PKCS12 之间的显著区别在于 JKS 是特定于 Java 的格式。相反,PKCS12 是一种标准化、不中立的方式,用于存储加密的私钥和证书。

以下是启用 mTLS 的示例配置:

quarkus.http.ssl.certificate.key-store-file=server-keystore.jks 
1

quarkus.http.ssl.certificate.key-store-password=the_key_store_secret
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks 
2

quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret
quarkus.http.ssl.client-auth=required 
3

quarkus.http.auth.permission.default.paths=/* 
4

quarkus.http.auth.permission.default.policy=authenticated
quarkus.http.insecure-requests=disabled 
5
Copy to Clipboard Toggle word wrap
1
服务器私钥所在的密钥存储。
2
从中加载可信证书的信任存储。
3
quarkus.http.ssl.client-auth 设置为 required 使服务器需要客户端证书。如果服务器应该接受没有证书的请求,您可以将它设置为 REQUEST。当支持多个身份验证方法时,此设置很有用。
4
定义一个策略,其中只有经过身份验证的用户可以访问应用程序中的资源。
5
禁用普通 HTTP 协议,要求所有请求使用 HTTPS。当您将 quarkus.http.ssl.client-auth 设置为 required 时,quarkus.http.insecure-requests 会自动禁用。

当传入请求与信任存储中的有效证书匹配时,您的应用程序可以通过注入 SecurityIdentity 获取主题,如下所示:

获取主题

@Inject
SecurityIdentity identity;

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
    return String.format("Hello, %s", identity.getPrincipal().getName());
}
Copy to Clipboard Toggle word wrap

您还可以使用以下示例中介绍的代码获取证书:

获取证书

import java.security.cert.X509Certificate;
import io.quarkus.security.credential.CertificateCredential;

CertificateCredential credential = identity.getCredential(CertificateCredential.class);
X509Certificate certificate = credential.getCertificate();
Copy to Clipboard Toggle word wrap

2.2.3.1. 将证书属性映射到角色

来自客户端证书的信息可用于将角色添加到 Quarkus 安全Identity

在检查客户端证书的通用名称(CN)属性后,您可以将新角色添加到 SecurityIdentity 中。添加新角色的最简单方法是将证书属性用于角色映射功能。

例如,您可以更新部分中显示的属性,它引入了 Mutual TLS 身份验证,如下所示:

quarkus.http.ssl.certificate.key-store-file=server-keystore.jks
quarkus.http.ssl.certificate.key-store-password=the_key_store_secret
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks
quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret
quarkus.http.ssl.client-auth=required
quarkus.http.insecure-requests=disabled

quarkus.http.auth.certificate-role-properties=cert-role-mappings.properties 
1


quarkus.http.auth.permission.certauthenticated.paths=/*   
2

quarkus.http.auth.permission.certauthenticated.policy=role-policy-cert 
3

quarkus.http.auth.policy.role-policy-cert.roles-allowed=user,admin     
4
Copy to Clipboard Toggle word wrap
1
cert-role-mappings.properties classpath 资源包含证书的 CN 值映射,格式为 CN=roleCN=role1,role2 等。让我们假设它包含三个条目: alice=user、admin、 bob=userjdoe=tester
2 3 4
使用 HTTP 安全策略要求 SecurityIdentity 必须具有 useradmin 角色,才能被授权请求。

根据前面的配置,如果客户端证书的 CN 属性等于 alicebob,如果请求等同于 jdoe,则请求被授权。

2.2.3.2. 使用证书属性来增强 SecurityIdentity

如果 角色选项的自动映射证书属性不适用,则始终可以注册 SecurityIdentityAugmentor。自定义 SecurityIdentityAugmentor 可以检查不同的客户端证书属性的值,并相应地增强 SecurityIdentity

有关自定义安全身份的更多信息,请参阅 Quarkus " 安全提示 和 tricks" 指南中的 安全身份自定义 部分。

Mutual TLS 身份验证 部分中,我们在 application.properties 文件中配置 mutual TLS 客户端身份验证,如下所示:

quarkus.tls.tls-config-1.key-store.p12.path=server-keystore.p12
quarkus.tls.tls-config-1.key-store.p12.password=the_key_store_secret
quarkus.tls.tls-config-1.trust-store.p12.path=server-truststore.p12
quarkus.tls.tls-config-1.trust-store.p12.password=the_trust_store_secret
quarkus.http.ssl.client-auth=required   
1

quarkus.http.tls-configuration-name=tls-config-1    
2
Copy to Clipboard Toggle word wrap
1
启用并需要 mutual TLS 客户端身份验证。
2
tls-config-1 TLS 配置用于 HTTP 服务器 TLS 通信。

io.quarkus.vertx.http.security.HttpSecurity CDI 事件允许您以编程方式配置 mutual TLS 身份验证,如下例所示:

TLS 配置示例

package org.acme.http.security;

import io.quarkus.tls.BaseTlsConfiguration;
import io.vertx.core.net.KeyCertOptions;
import io.vertx.core.net.KeyStoreOptions;
import io.vertx.core.net.SSLOptions;
import io.vertx.core.net.TrustOptions;

import java.util.Set;
import java.util.concurrent.TimeUnit;

public class MyTlsConfiguration extends BaseTlsConfiguration {

    @Override
    public KeyCertOptions getKeyStoreOptions() {
        return new KeyStoreOptions()
                .setPath("/tmp/certs/server-keystore.p12")
                .setPassword("the_key_store_secret")
                .setType("PKCS12");
    }

    @Override
    public TrustOptions getTrustStoreOptions() {
        return new KeyStoreOptions()
                .setPath("/tmp/certs/server-truststore.jks")
                .setPassword("the_trust_store_secret")
                .setType("PKCS12");
    }

    @Override
    public SSLOptions getSSLOptions() {
        SSLOptions options = new SSLOptions();
        options.setKeyCertOptions(getKeyStoreOptions());
        options.setTrustOptions(getTrustStoreOptions());
        options.setSslHandshakeTimeoutUnit(TimeUnit.SECONDS);
        options.setSslHandshakeTimeout(10);
        options.setEnabledSecureTransportProtocols(Set.of("TLSv1.3", "TLSv1.2"));
        return options;
    }

}
Copy to Clipboard Toggle word wrap

双向 TLS 客户端身份验证配置示例

package org.acme.http.security;

import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;

public class MutualTlsClientAuthConfig {

    void configure(@Observes HttpSecurity httpSecurity) {
        httpSecurity.mTLS("tls-config-1", new MyTlsConfiguration());    
1

    }

}
Copy to Clipboard Toggle word wrap

1
启用并需要 mutual TLS 客户端身份验证,并将 tls-config-1 TLS 配置用于 HTTP 服务器 TLS 通信。tls-config-1 TLS 配置在 TLS registry 中注册。

也可以将证书属性映射到角色。让我们考虑在 Mapping certificate 属性到 roles 部分所解释的示例:

quarkus.tls.tls-config-1.key-store.p12.path=server-keystore.p12
quarkus.tls.tls-config-1.key-store.p12.password=the_key_store_secret
quarkus.tls.tls-config-1.trust-store.p12.path=server-truststore.p12
quarkus.tls.tls-config-1.trust-store.p12.password=the_trust_store_secret
quarkus.http.ssl.client-auth=required
quarkus.http.tls-configuration-name=tls-config-1
quarkus.http.auth.certificate-role-properties=cert-role-mappings.properties
Copy to Clipboard Toggle word wrap

带有编程集的配置类似如下:

package org.acme.http.security;

import io.quarkus.vertx.http.security.MTLS;
import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;

public class MutualTlsClientAuthConfig {

    void configure(@Observes HttpSecurity httpSecurity) {
        httpSecurity.mTLS(MTLS.builder()
                .tls("tls-config-1", new MyTlsConfiguration())
                .rolesMapping("CN-value", "user", "admin")
                .build());
    }

}
Copy to Clipboard Toggle word wrap

此 API 还允许您使用证书来增强 SecurityIdentity

quarkus.http.tls-configuration-name=tls-config-1
quarkus.tls.tls-config-1.key-store.p12.path=server-keystore.p12
quarkus.tls.tls-config-1.key-store.p12.password=the_key_store_secret
quarkus.tls.tls-config-1.trust-store.p12.path=server-truststore.jks
quarkus.tls.tls-config-1.trust-store.p12.password=the_trust_store_secret
Copy to Clipboard Toggle word wrap
package org.acme.http.security;

import io.quarkus.vertx.http.security.HttpSecurity;
import io.quarkus.vertx.http.security.MTLS;
import jakarta.enterprise.event.Observes;

import java.util.Set;

public class MutualTlsClientAuthConfig {

    void configure(@Observes HttpSecurity httpSecurity) {
        httpSecurity.mTLS(MTLS.builder()
                .certificateToRolesMapper(x509Certificate -> {   
1

                    final Set<String> securityIdentityRoles;

                    // replace this logic with your own certificate to roles mapping
                    if (x509Certificate.getIssuerX500Principal() != null
                            && "CN=quarkus.io".equals(x509Certificate.getIssuerX500Principal().getName())) {
                        securityIdentityRoles = Set.of("admin");
                    } else {
                        securityIdentityRoles = Set.of();
                    }
                    return securityIdentityRoles;
                })
                .build());
    }

}
Copy to Clipboard Toggle word wrap
1
Using certificate attributes to increased SecurityIdentity 部分中,我们提到了 SecurityIdentityAugmentor 可用于将客户端证书属性值映射到 SecurityIdentity 角色。MTLS API 允许您定义这样的角色映射。
重要

如果 Quarkus 在启动失败后以 DEV 模式启动 HTTP 服务器,Quarkus 可能需要回退到 application.properties 文件中提供的配置。这是一个已知的限制。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat