1.2. Quickstart


1.2.1. 解决方案

我们建议您按照后续部分中的说明来逐步创建应用程序步骤。如果您愿意,可以进入已完成的示例。

要访问示例,请克隆 Git 存储库或下载存档:

已完成的解决方案位于 security-jwt-quickstart 目录中

1.2.2. 创建 Maven 项目

首先,使用以下命令创建新项目:

  • 使用 Quarkus CLI:

    quarkus create app org.acme:security-jwt-quickstart \
        --extension='rest-jackson,smallrye-jwt,smallrye-jwt-build' \
        --no-code
    cd security-jwt-quickstart
    Copy to Clipboard Toggle word wrap

    要创建 Gradle 项目,请添加-- gradle or --gradle-kotlin-dsl 选项。

    有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。

  • 使用 Maven:

    mvn com.redhat.quarkus.platform:quarkus-maven-plugin:3.20.1:create \
        -DprojectGroupId=org.acme \
        -DprojectArtifactId=security-jwt-quickstart \
        -Dextensions='rest-jackson,smallrye-jwt,smallrye-jwt-build' \
        -DnoCode
    cd security-jwt-quickstart
    Copy to Clipboard Toggle word wrap

    要创建 Gradle 项目,请添加 -DbuildTool=gradle or -DbuildTool=gradle-kotlin-dsl 选项。

对于 Windows 用户:

  • 如果使用 cmd,(不要使用反向斜杠 \ 并将所有内容放在同一行中)
  • 如果使用 Powershell,则双引号中的 wrap -D 参数,如 "-DprojectArtifactId=security-jwt-quickstart"

此命令生成 Maven 项目并导入 smallrye-jwt 扩展,其包含 MicroProfile JWT RBAC 支持。

如果您已经配置了 Quarkus 项目,您可以通过在项目基本目录中运行以下命令来将 smallrye-jwt 扩展添加到项目中:

  • 使用 Quarkus CLI:

    quarkus extension add smallrye-jwt,smallrye-jwt-build
    Copy to Clipboard Toggle word wrap
  • 使用 Maven:

    ./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'
    Copy to Clipboard Toggle word wrap
  • 使用 Gradle:

    ./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build'
    Copy to Clipboard Toggle word wrap

这个命令在构建文件中添加以下依赖项:

  • 使用 Maven:

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-smallrye-jwt</artifactId>
    </dependency>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-smallrye-jwt-build</artifactId>
    </dependency>
    Copy to Clipboard Toggle word wrap
  • 使用 Gradle:

    implementation("io.quarkus:quarkus-smallrye-jwt")
    implementation("io.quarkus:quarkus-smallrye-jwt-build")
    Copy to Clipboard Toggle word wrap

1.2.3. 检查 Jakarta REST 资源

src/main/java/org/acme/security/jwt/TokenSecuredResource.java 中创建一个 REST 端点,其内容如下:

REST 端点 V1

package org.acme.security.jwt;

import jakarta.annotation.security.PermitAll;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;

import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/secured")
public class TokenSecuredResource {

    @Inject
    JsonWebToken jwt; 
1


    @GET
    @Path("permit-all")
    @PermitAll 
2

    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@Context SecurityContext ctx) {
        return getResponseString(ctx); 
3

    }

    private String getResponseString(SecurityContext ctx) {
        String name;
        if (ctx.getUserPrincipal() == null) { 
4

            name = "anonymous";
        } else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) { 
5

            throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
        } else {
            name = ctx.getUserPrincipal().getName(); 
6

        }
        return String.format("hello %s,"
            + " isHttps: %s,"
            + " authScheme: %s,"
            + " hasJWT: %s",
            name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt()); 
7

    }

    private boolean hasJwt() {
        return jwt.getClaimNames() != null;
    }
}
Copy to Clipboard Toggle word wrap

1
JsonWebToken 接口被注入,提供对与当前经过身份验证的用户关联的声明的访问。这个接口扩展了 java.security.Principal
2
@PermitAll 是标准的 Jakarta 安全注释。表示给定端点可以被所有调用者访问,无论是否通过身份验证。
3
Jakarta REST SecurityContext 被注入,以检查请求的安全状态。getResponseString () 函数生成响应。
4
通过检查请求用户/调用者 Principal 是否针对 null 检查调用是否不安全。
5
确保 PrincipalJsonWebToken 中的名称与 JsonWebToken 匹配,因为 JsonWebToken 代表当前的 主体
6
检索 Principal 的名称。
7
构建包含调用者名称的 isSecure ()getAuthenticationScheme () 状态的响应,以及是否注入了非null JsonWebToken

1.2.4. 在 dev 模式下运行应用程序

现在,您可以使用以下命令以 dev 模式运行应用程序:

  • 使用 Quarkus CLI:

    quarkus dev
    Copy to Clipboard Toggle word wrap
  • 使用 Maven:

    ./mvnw quarkus:dev
    Copy to Clipboard Toggle word wrap
  • 使用 Gradle:

    ./gradlew --console=plain quarkusDev
    Copy to Clipboard Toggle word wrap

然后,您应该看到类似以下示例的输出:

quarkus:dev output

[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< org.acme:security-jwt-quickstart >-----------------------
[INFO] Building security-jwt-quickstart 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...
Listening for transport dt_socket at address: 5005
2020-07-15 16:09:50,883 INFO  [io.quarkus] (Quarkus Main Thread) security-jwt-quickstart 1.0.0-SNAPSHOT on JVM (powered by Quarkus 999-SNAPSHOT) started in 1.073s. Listening on: http://0.0.0.0:8080
2020-07-15 16:09:50,885 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2020-07-15 16:09:50,885 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, mutiny, rest, rest-jackson, security, smallrye-context-propagation, smallrye-jwt, vertx, vertx-web]
Copy to Clipboard Toggle word wrap

现在,REST 端点正在运行,您可以使用命令行工具(如 curl)访问它:

/secured/permit-allcurl 命令

$ curl http://127.0.0.1:8080/secured/permit-all; echo
Copy to Clipboard Toggle word wrap

这个命令返回以下响应:

hello anonymous, isHttps: false, authScheme: null, hasJWT: false
Copy to Clipboard Toggle word wrap

您没有在我们的请求中提供任何 JWT,因此您不会预期端点查看任何安全状态,并且响应与其一致:

  • 用户名是 匿名的。
  • isHttpsfalse,因为不使用 https
  • authSchemenull
  • 的JWTfalse

使用 Ctrl-C 停止 Quarkus 服务器。

现在,我们来保证.查看新端点方法 helloRolesAllowed,如下所示:

REST 端点 V2

package org.acme.security.jwt;

import jakarta.annotation.security.PermitAll;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;

import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/secured")
public class TokenSecuredResource {

    @Inject
    JsonWebToken jwt; 
1


    @GET
    @Path("permit-all")
    @PermitAll
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@Context SecurityContext ctx) {
        return getResponseString(ctx);
    }

    @GET
    @Path("roles-allowed") 
2

    @RolesAllowed({ "User", "Admin" }) 
3

    @Produces(MediaType.TEXT_PLAIN)
    public String helloRolesAllowed(@Context SecurityContext ctx) {
        return getResponseString(ctx) + ", birthdate: " + jwt.getClaim("birthdate").toString(); 
4

    }

    private String getResponseString(SecurityContext ctx) {
        String name;
        if (ctx.getUserPrincipal() == null) {
            name = "anonymous";
        } else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) {
            throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
        } else {
            name = ctx.getUserPrincipal().getName();
        }
        return String.format("hello %s,"
            + " isHttps: %s,"
            + " authScheme: %s,"
            + " hasJWT: %s",
            name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt());
    }

    private boolean hasJwt() {
        return jwt.getClaimNames() != null;
    }
}
Copy to Clipboard Toggle word wrap

1
注入 JsonWebToken 以访问 JWT 中的声明。
2
此端点通过 /secured/roles-allowed 公开。
3
@RolesAllowed 注释限制对具有"User"或"Admin"角色的用户的访问。
4
响应构建方式与 hello 方法相似,添加了直接从注入的 JsonWebToken 检索的 birthdate 声明。

在添加了 TokenSecuredResource 后,重新运行 ./mvnw quarkus:dev 命令,然后尝试 curl -v http://127.0.0.1:8080/secured/roles-allowed; echo 以尝试访问新端点。

您的输出应如下所示:

/secured/roles-allowedcurl 命令

$ curl -v http://127.0.0.1:8080/secured/roles-allowed; echo
Copy to Clipboard Toggle word wrap

这个命令返回以下响应:

*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /secured/roles-allowed HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Connection: keep-alive
< Content-Type: text/html;charset=UTF-8
< Content-Length: 14
< Date: Sun, 03 Mar 2019 16:32:34 GMT
<
* Connection #0 to host 127.0.0.1 left intact
Copy to Clipboard Toggle word wrap

卓越的.您没有在请求中提供 JWT,因此正确拒绝对端点的访问。相反,您会收到 HTTP 401 Unauthorized 错误。

若要访问端点,您必须获取并在请求中包含有效的 JWT。这涉及两个步骤:

  1. 使用必要信息配置 SmallRye JWT 扩展以验证 JWT。
  2. 使用适当的声明生成 JWT 以匹配配置。

1.2.5. 配置 SmallRye JWT 扩展安全信息

使用以下内容创建 security-jwt-quickstart/src/main/resources/application.properties

TokenSecuredResource的应用程序属性

mp.jwt.verify.publickey.location=publicKey.pem 
1

mp.jwt.verify.issuer=https://example.com/issuer 
2


quarkus.native.resources.includes=publicKey.pem 
3
Copy to Clipboard Toggle word wrap

1
指定 classpath 上公钥文件 publicKey.pem 的位置。请参阅为 添加此密钥 添加公钥。
2
将预期的签发者定义为 https://example.com/issuer
3
确保 publicKey.pem 文件作为原生可执行文件中的资源包含。

1.2.6. 添加公钥

JWT 规范定义 可以使用的 JWT 的各种安全性级别。MicroProfile JWT RBAC 规范需要使用 RSA-256 签名算法签名的 JWT。这反过来需要一个 RSA 公钥对。在 REST 端点服务器端,您需要配置 RSA 公钥的位置,以验证与请求一起发送的 JWT。mp.jwt.verify.publickey.location=publicKey.pem 设置预期之前配置的公钥为 publicKey.pem。要达到此目的,请将以下内容复制到 security-jwt-quickstart/src/main/resources/publicKey.pem 文件中。

RSA 公钥 PEM 内容

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
nQIDAQAB
-----END PUBLIC KEY-----
Copy to Clipboard Toggle word wrap

1.2.7. 生成 JWT

通常,从 Keycloak 等身份管理器获取 JWT。但是,对于此快速入门,您可以使用 smallrye-jwt 提供的 JWT 生成 API 自行生成。如需更多信息,请参阅使用 SmallRye JWT 生成 JWT 令牌

从以下列表中获取代码,并将它放入 security-jwt-quickstart/src/test/java/org/acme/security/jwt/GenerateToken.java 中:

GenerateToken 主驱动程序类

package org.acme.security.jwt;

import java.util.Arrays;
import java.util.HashSet;

import org.eclipse.microprofile.jwt.Claims;
import io.smallrye.jwt.build.Jwt;

/**
 * A utility class to generate and print a JWT token string to stdout.
 */
public class GenerateToken {

    /**
     * Generates and prints a JWT token.
     */
    public static void main(String[] args) {
        String token = Jwt.issuer("https://example.com/issuer") 
1

                .upn("jdoe@quarkus.io") 
2

                .groups(new HashSet<>(Arrays.asList("User", "Admin"))) 
3

                .claim(Claims.birthdate.name(), "2001-07-13") 
4

                .sign();

        System.out.println(token);
        System.exit(0);
    }
}
Copy to Clipboard Toggle word wrap

1
在 JWT 中设置 iss (issuer)声明。这个值必须与服务器端 mp.jwt.verify.issuer 配置匹配,以便令牌被视为有效。
2
指定 upn (User Principal Name)声明,MicroProfile JWT RBAC 规范将它定义为识别容器安全 API 中 Principal 的首选声明。
3
定义 groups 声明,它提供组成员资格和分配给 JWT bearer 的顶级角色。
4
添加 birthdate 声明。由于这被视为敏感信息,因此请考虑加密声明,如 使用 SmallRye JWT 生成 JWT 令牌 中所述。

请注意,为此代码正常工作,您需要与您在 TokenSecuredResource 应用程序中的公钥对应的 RSA 私钥的内容。取以下 PEM 内容并将其放入 security-jwt-quickstart/src/test/resources/privateKey.pem 中:

RSA 私钥 PEM 内容

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
f3cg+fr8aou7pr9SHhJlZCU=
-----END PRIVATE KEY-----
Copy to Clipboard Toggle word wrap

之后,您要配置 smallrye.jwt.sign.key.location 属性来指定私钥的位置。

使用 OpenSSL 生成密钥

也可以使用 OpenSSL 命令行工具生成公钥和私钥对。

用于生成密钥的 OpenSSL 命令

openssl genrsa -out rsaPrivateKey.pem 2048
openssl rsa -pubout -in rsaPrivateKey.pem -out publicKey.pem
Copy to Clipboard Toggle word wrap

需要额外的步骤来生成私钥并将其转换为 PKCS"8 格式,通常用于安全密钥存储和传输。

用于执行转换的 OpenSSL 命令

openssl pkcs8 -topk8 -nocrypt -inform pem -in rsaPrivateKey.pem -outform pem -out privateKey.pem
Copy to Clipboard Toggle word wrap

您可以使用生成的密钥对而不是这个快速入门中使用的密钥对。

在为 TokenSecuredResource 端点生成 JSON Web Token (JWT)之前,请确保 应用正在运行

接下来,使用以下命令生成 JWT:

JWT 生成输出示例

$ mvn exec:java -Dexec.mainClass=org.acme.security.jwt.GenerateToken -Dexec.classpathScope=test -Dsmallrye.jwt.sign.key.location=privateKey.pem
Copy to Clipboard Toggle word wrap

JWT 字符串是由三个部分组成的 Base64 URL 编码字符串,用 . 字符分隔:

  1. 标头,其中包含令牌的元数据,如签名算法。
  2. 有效负载也称为 "claims",其中包括令牌的声明或数据。
  3. 签名,验证令牌的完整性。

现在,让我们使用它来向 /secured/roles-allowed 端点发出安全请求。确保 Quarkus 服务器仍然以 dev 模式运行,然后运行以下命令,确保使用上一步中生成的 JWT 版本:

使用 JWT 进行 /secured/roles-allowedcurl 命令

$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed; echo
Copy to Clipboard Toggle word wrap

确保将生成的令牌用作 HTTP Authorization Bearer 方案值。

这个命令返回以下响应:

hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
Copy to Clipboard Toggle word wrap

成功!现在您有以下内容:

  • 非匿名调用者名称: jdoe@quarkus.io
  • 身份验证方案: Bearer
  • 非null JsonWebToken
  • birthdate 声明值

1.2.9. 使用 JsonWebToken 和声明注入

现在,您可以生成 JWT 以访问我们的安全 REST 端点,让我们看到您可以使用 JsonWebToken 接口和 JWT 声明进行更多的操作。org.eclipse.microprofile.jwt.JsonWebToken 接口扩展了 java.security.Principal 接口,并且是由之前使用的 jakarta.ws.ws.rs.core.SecurityContext SerialgetUserPrincipal () 调用返回的对象类型。这意味着,不使用 CDI 但可以访问 REST 容器 SecurityContext 的代码可以存放调用者 JsonWebToken 接口。

JsonWebToken 接口定义了在底层 JWT 中访问声明的方法。它为 MicroProfile JWT RBAC 规范和 JWT 中可能存在的任意声明提供常见声明的访问权限。

也可以注入所有 JWT 声明。我们使用另一个端点 /secured/roles-allowed-admin 扩展 TokenSecuredResource,该端点使用注入的 birthdate 声明(而不是从 JsonWebToken获取):

package org.acme.security.jwt;

import jakarta.annotation.security.PermitAll;
import jakarta.annotation.security.RolesAllowed;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;

import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/secured")
@RequestScoped 
1

public class TokenSecuredResource {

    @Inject
    JsonWebToken jwt; 
2

    @Inject
    @Claim(standard = Claims.birthdate)
    String birthdate; 
3


    @GET
    @Path("permit-all")
    @PermitAll
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(@Context SecurityContext ctx) {
        return getResponseString(ctx);
    }

    @GET
    @Path("roles-allowed")
    @RolesAllowed({ "User", "Admin" })
    @Produces(MediaType.TEXT_PLAIN)
    public String helloRolesAllowed(@Context SecurityContext ctx) {
        return getResponseString(ctx) + ", birthdate: " + jwt.getClaim("birthdate").toString();
    }

    @GET
    @Path("roles-allowed-admin")
    @RolesAllowed("Admin")
    @Produces(MediaType.TEXT_PLAIN)
    public String helloRolesAllowedAdmin(@Context SecurityContext ctx) {
        return getResponseString(ctx) + ", birthdate: " + birthdate; 
4

    }

    private String getResponseString(SecurityContext ctx) {
        String name;
        if (ctx.getUserPrincipal() == null) {
            name = "anonymous";
        } else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) {
            throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
        } else {
            name = ctx.getUserPrincipal().getName();
        }
        return String.format("hello %s,"
            + " isHttps: %s,"
            + " authScheme: %s,"
            + " hasJWT: %s",
            name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt());
    }

    private boolean hasJwt() {
        return jwt.getClaimNames() != null;
    }
}
Copy to Clipboard Toggle word wrap
1
需要 @RequestScoped 范围,才能将 birthdate 声明注入为 String
2
此处注入了 JsonWebToken,为所有声明和 JWT 相关的信息提供访问权限。
3
birthdate 声明被注入为 String。这重点介绍了 @RequestScoped 范围必须的原因。
4
注入的 birthdate 声明直接用于构造响应。

现在再次生成令牌并运行:

$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed-admin; echo
Copy to Clipboard Toggle word wrap

确保将生成的令牌用作 HTTP Authorization Bearer 方案值。

这个命令返回以下响应:

hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
Copy to Clipboard Toggle word wrap

1.2.10. 在 JVM 模式下运行应用程序

您可以将应用程序作为标准 Java 应用程序运行。

  1. 编译应用程序:

    • 使用 Quarkus CLI:

      quarkus build
      Copy to Clipboard Toggle word wrap
    • 使用 Maven:

      ./mvnw install
      Copy to Clipboard Toggle word wrap
    • 使用 Gradle:

      ./gradlew build
      Copy to Clipboard Toggle word wrap
  2. 运行应用程序:

    java -jar target/quarkus-app/quarkus-run.jar
    Copy to Clipboard Toggle word wrap

1.2.11. 以原生模式运行应用程序

您可以在不进行任何修改的情况下,将相同的演示编译为原生模式。这意味着您不再需要在生产环境中安装 JVM。运行时技术包含在生成的二进制中,并经过优化,以便以最少的资源运行。

编译时间需要一些时间,因此默认禁用此步骤。

  1. 通过启用 原生 配置集来再次构建应用程序:

    • 使用 Quarkus CLI:

      quarkus build --native
      Copy to Clipboard Toggle word wrap
    • 使用 Maven:

      ./mvnw install -Dnative
      Copy to Clipboard Toggle word wrap
    • 使用 Gradle:

      ./gradlew build -Dquarkus.native.enabled=true
      Copy to Clipboard Toggle word wrap
  2. 直接运行以下二进制文件:

    ./target/security-jwt-quickstart-1.0.0-SNAPSHOT-runner
    Copy to Clipboard Toggle word wrap

1.2.12. 探索解决方案

security-jwt-quickstart 目录 存储库包含此快速入门指南中涵盖的所有版本,以及用于使用注入的 JsonWebToken 令牌及其声明通过 CDI API 演示子资源的其他端点。

我们建议您探索 security-jwt-quickstart 目录,并查看快速入门解决方案,以了解更多有关 SmallRye JWT 扩展的功能。

Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2026 Red Hat
返回顶部