1.2. Quickstart
1.2.1. 解决方案 复制链接链接已复制到粘贴板!
我们建议您按照后续部分中的说明来逐步创建应用程序步骤。如果您愿意,可以进入已完成的示例。
要访问示例,请克隆 Git 存储库或下载存档:
-
克隆存储库:
git clone https://github.com/quarkusio/quarkus-quickstarts.git -b 3.20。 - 下载 存档。
已完成的解决方案位于 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-quickstartquarkus create app org.acme:security-jwt-quickstart \ --extension='rest-jackson,smallrye-jwt,smallrye-jwt-build' \ --no-code cd security-jwt-quickstartCopy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加--
gradle or--gradle-kotlin-dsl选项。有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。
使用 Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加
-DbuildTool=gradleor-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
quarkus extension add smallrye-jwt,smallrye-jwt-buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'
./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build'
./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
这个命令在构建文件中添加以下依赖项:
使用 Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
implementation("io.quarkus:quarkus-smallrye-jwt") implementation("io.quarkus:quarkus-smallrye-jwt-build")implementation("io.quarkus:quarkus-smallrye-jwt") implementation("io.quarkus:quarkus-smallrye-jwt-build")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.2.3. 检查 Jakarta REST 资源 复制链接链接已复制到粘贴板!
在 src/main/java/org/acme/security/jwt/TokenSecuredResource.java 中创建一个 REST 端点,其内容如下:
REST 端点 V1
- 1
JsonWebToken接口被注入,提供对与当前经过身份验证的用户关联的声明的访问。这个接口扩展了java.security.Principal。- 2
@PermitAll是标准的 Jakarta 安全注释。表示给定端点可以被所有调用者访问,无论是否通过身份验证。- 3
- Jakarta REST
SecurityContext被注入,以检查请求的安全状态。getResponseString ()函数生成响应。 - 4
- 通过检查请求用户/调用者
Principal是否针对 null 检查调用是否不安全。 - 5
- 确保
Principal和JsonWebToken中的名称与 JsonWebToken 匹配,因为JsonWebToken代表当前的主体。 - 6
- 检索
Principal的名称。 - 7
- 构建包含调用者名称的
isSecure ()和getAuthenticationScheme ()状态的响应,以及是否注入了非nullJsonWebToken。
1.2.4. 在 dev 模式下运行应用程序 复制链接链接已复制到粘贴板!
现在,您可以使用以下命令以 dev 模式运行应用程序:
使用 Quarkus CLI:
quarkus dev
quarkus devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:dev
./mvnw quarkus:devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew --console=plain quarkusDev
./gradlew --console=plain quarkusDevCopy to Clipboard Copied! Toggle word wrap Toggle overflow
然后,您应该看到类似以下示例的输出:
quarkus:dev output
现在,REST 端点正在运行,您可以使用命令行工具(如 curl)访问它:
/secured/permit-all的 curl 命令
curl http://127.0.0.1:8080/secured/permit-all; echo
$ curl http://127.0.0.1:8080/secured/permit-all; echo
这个命令返回以下响应:
hello anonymous, isHttps: false, authScheme: null, hasJWT: false
hello anonymous, isHttps: false, authScheme: null, hasJWT: false
您没有在我们的请求中提供任何 JWT,因此您不会预期端点查看任何安全状态,并且响应与其一致:
-
用户名是匿名的。 -
isHttps为false,因为不使用https。 -
authScheme是null。 -
的JWT为false。
使用 Ctrl-C 停止 Quarkus 服务器。
现在,我们来保证.查看新端点方法 helloRolesAllowed,如下所示:
REST 端点 V2
在添加了 TokenSecuredResource 后,重新运行 ./mvnw quarkus:dev 命令,然后尝试 curl -v http://127.0.0.1:8080/secured/roles-allowed; echo 以尝试访问新端点。
您的输出应如下所示:
/secured/roles-allowed的 curl 命令
curl -v http://127.0.0.1:8080/secured/roles-allowed; echo
$ curl -v http://127.0.0.1:8080/secured/roles-allowed; echo
这个命令返回以下响应:
卓越的.您没有在请求中提供 JWT,因此正确拒绝对端点的访问。相反,您会收到 HTTP 401 Unauthorized 错误。
若要访问端点,您必须获取并在请求中包含有效的 JWT。这涉及两个步骤:
- 使用必要信息配置 SmallRye JWT 扩展以验证 JWT。
- 使用适当的声明生成 JWT 以匹配配置。
1.2.5. 配置 SmallRye JWT 扩展安全信息 复制链接链接已复制到粘贴板!
使用以下内容创建 security-jwt-quickstart/src/main/resources/application.properties :
TokenSecuredResource的应用程序属性
mp.jwt.verify.publickey.location=publicKey.pem mp.jwt.verify.issuer=https://example.com/issuer quarkus.native.resources.includes=publicKey.pem
mp.jwt.verify.publickey.location=publicKey.pem
mp.jwt.verify.issuer=https://example.com/issuer
quarkus.native.resources.includes=publicKey.pem
- 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 内容
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 主驱动程序类
- 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 内容
之后,您要配置 smallrye.jwt.sign.key.location 属性来指定私钥的位置。
也可以使用 OpenSSL 命令行工具生成公钥和私钥对。
用于生成密钥的 OpenSSL 命令
openssl genrsa -out rsaPrivateKey.pem 2048 openssl rsa -pubout -in rsaPrivateKey.pem -out publicKey.pem
openssl genrsa -out rsaPrivateKey.pem 2048
openssl rsa -pubout -in rsaPrivateKey.pem -out publicKey.pem
需要额外的步骤来生成私钥并将其转换为 PKCS"8 格式,通常用于安全密钥存储和传输。
用于执行转换的 OpenSSL 命令
openssl pkcs8 -topk8 -nocrypt -inform pem -in rsaPrivateKey.pem -outform pem -out privateKey.pem
openssl pkcs8 -topk8 -nocrypt -inform pem -in rsaPrivateKey.pem -outform pem -out privateKey.pem
您可以使用生成的密钥对而不是这个快速入门中使用的密钥对。
在为 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
$ mvn exec:java -Dexec.mainClass=org.acme.security.jwt.GenerateToken -Dexec.classpathScope=test -Dsmallrye.jwt.sign.key.location=privateKey.pem
JWT 字符串是由三个部分组成的 Base64 URL 编码字符串,用 . 字符分隔:
- 标头,其中包含令牌的元数据,如签名算法。
- 有效负载也称为 "claims",其中包括令牌的声明或数据。
- 签名,验证令牌的完整性。
1.2.8. 最后,对 /secured/roles-allowed进行安全访问 复制链接链接已复制到粘贴板!
现在,让我们使用它来向 /secured/roles-allowed 端点发出安全请求。确保 Quarkus 服务器仍然以 dev 模式运行,然后运行以下命令,确保使用上一步中生成的 JWT 版本:
使用 JWT 进行 /secured/roles-allowed 的 curl 命令
curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed; echo
$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed; echo
确保将生成的令牌用作 HTTP Authorization Bearer 方案值。
这个命令返回以下响应:
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
成功!现在您有以下内容:
-
非匿名调用者名称:
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获取):
现在再次生成令牌并运行:
curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed-admin; echo
$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed-admin; echo
确保将生成的令牌用作 HTTP Authorization Bearer 方案值。
这个命令返回以下响应:
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
1.2.10. 在 JVM 模式下运行应用程序 复制链接链接已复制到粘贴板!
您可以将应用程序作为标准 Java 应用程序运行。
编译应用程序:
使用 Quarkus CLI:
quarkus build
quarkus buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install
./mvnw installCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build
./gradlew buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow
运行应用程序:
java -jar target/quarkus-app/quarkus-run.jar
java -jar target/quarkus-app/quarkus-run.jarCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.2.11. 以原生模式运行应用程序 复制链接链接已复制到粘贴板!
您可以在不进行任何修改的情况下,将相同的演示编译为原生模式。这意味着您不再需要在生产环境中安装 JVM。运行时技术包含在生成的二进制中,并经过优化,以便以最少的资源运行。
编译时间需要一些时间,因此默认禁用此步骤。
通过启用
原生配置集来再次构建应用程序:使用 Quarkus CLI:
quarkus build --native
quarkus build --nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install -Dnative
./mvnw install -DnativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build -Dquarkus.native.enabled=true
./gradlew build -Dquarkus.native.enabled=trueCopy to Clipboard Copied! Toggle word wrap Toggle overflow
直接运行以下二进制文件:
./target/security-jwt-quickstart-1.0.0-SNAPSHOT-runner
./target/security-jwt-quickstart-1.0.0-SNAPSHOT-runnerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.2.12. 探索解决方案 复制链接链接已复制到粘贴板!
security-jwt-quickstart 目录 存储库包含此快速入门指南中涵盖的所有版本,以及用于使用注入的 JsonWebToken 令牌及其声明通过 CDI API 演示子资源的其他端点。
我们建议您探索 security-jwt-quickstart 目录,并查看快速入门解决方案,以了解更多有关 SmallRye JWT 扩展的功能。