使用 OpenID Connect (OIDC) 授权码流保护 Web 应用程序
了解如何使用 Quarkus OpenID Connect (OIDC) 扩展的 OIDC 授权码流程机制来保护应用程序 HTTP 端点,从而提供强大的身份验证和授权。
有关更多信息,请参阅用于保护 Web 应用程序的 OIDC 代码流程机制。
要了解如何将 Apple、Facebook、GitHub、Google、Mastodon、Microsoft、Spotify、Twitch 和 X(以前的 Twitter)等知名社交提供商与 Quarkus OIDC 一起使用,请参阅配置知名的 OpenID Connect 提供商。 另请参阅Quarkus 中的身份验证机制。
如果您想使用 OIDC Bearer 令牌身份验证来保护您的服务应用程序,请参阅OIDC Bearer 令牌身份验证。
先决条件
要完成本指南,您需要
-
大约 15 分钟
-
一个 IDE
-
已安装 JDK 17+ 并正确配置了
JAVA_HOME
-
Apache Maven 3.9.9
-
一个正常工作的容器运行时(Docker 或 Podman)
-
如果您想使用它,可以选择 Quarkus CLI
-
如果您想构建本机可执行文件(或者如果您使用本机容器构建,则为 Docker),可以选择安装 Mandrel 或 GraalVM 并进行适当的配置
解决方案
请按照以下章节中的说明逐步创建应用程序。或者,您可以直接转到已完成的示例。
运行 git clone https://github.com/quarkusio/quarkus-quickstarts.git
命令克隆 Git 存储库。 或者,下载存档。
解决方案位于 security-openid-connect-web-authentication-quickstart
目录中。
1. 创建 Maven 项目
首先,我们需要一个新项目。 运行以下命令创建一个新项目
对于 Windows 用户
-
如果使用 cmd,(不要使用反斜杠
\
并将所有内容放在同一行上) -
如果使用 Powershell,请将
-D
参数括在双引号中,例如"-DprojectArtifactId=security-openid-connect-web-authentication-quickstart"
如果您已经配置了 Quarkus 项目,则可以通过在项目基本目录中运行以下命令将 oidc
扩展添加到您的项目中
quarkus extension add oidc
./mvnw quarkus:add-extension -Dextensions='oidc'
./gradlew addExtension --extensions='oidc'
这会将以下依赖项添加到您的构建文件中
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
</dependency>
implementation("io.quarkus:quarkus-oidc")
2. 编写应用程序
让我们编写一个简单的 Jakarta REST 资源,该资源具有在授权码授予响应中返回的所有令牌注入
package org.acme.security.openid.connect.web.authentication;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;
import io.quarkus.oidc.IdToken;
import io.quarkus.oidc.RefreshToken;
@Path("/tokens")
public class TokenResource {
/**
* Injection point for the ID token issued by the OpenID Connect provider
*/
@Inject
@IdToken
JsonWebToken idToken;
/**
* Injection point for the access token issued by the OpenID Connect provider
*/
@Inject
JsonWebToken accessToken;
/**
* Injection point for the refresh token issued by the OpenID Connect provider
*/
@Inject
RefreshToken refreshToken;
/**
* Returns the tokens available to the application.
* This endpoint exists only for demonstration purposes.
* Do not expose these tokens in a real application.
*
* @return an HTML page containing the tokens available to the application.
*/
@GET
@Produces("text/html")
public String getTokens() {
StringBuilder response = new StringBuilder().append("<html>")
.append("<body>")
.append("<ul>");
Object userName = this.idToken.getClaim(Claims.preferred_username);
if (userName != null) {
response.append("<li>username: ").append(userName.toString()).append("</li>");
}
Object scopes = this.accessToken.getClaim("scope");
if (scopes != null) {
response.append("<li>scopes: ").append(scopes.toString()).append("</li>");
}
response.append("<li>refresh_token: ").append(refreshToken.getToken() != null).append("</li>");
return response.append("</ul>").append("</body>").append("</html>").toString();
}
}
此端点注入了 ID、访问和刷新令牌。 它从 ID 令牌返回 preferred_username
声明,从访问令牌返回 scope
声明,以及刷新令牌可用性状态。
只有在端点需要使用 ID 令牌与当前经过身份验证的用户交互,或者使用访问令牌代表此用户访问下游服务时,才需要注入令牌。
有关更多信息,请参阅参考指南的访问 ID 和访问令牌部分。
3. 配置应用程序
OIDC 扩展允许您使用 src/main/resources
目录中的 application.properties
文件定义配置。
%prod.quarkus.oidc.auth-server-url=https://:8180/realms/quarkus
quarkus.oidc.client-id=frontend
quarkus.oidc.credentials.secret=secret
quarkus.oidc.application-type=web-app
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
这是在启用应用程序身份验证时可以拥有的最简单的配置。
quarkus.oidc.client-id
属性引用 OIDC 提供程序颁发的 client_id
,quarkus.oidc.credentials.secret
属性设置客户端密码。
quarkus.oidc.application-type
属性设置为 web-app
,以告知 Quarkus 您要启用 OIDC 授权码流程,以便将用户重定向到 OIDC 提供程序进行身份验证。
最后,quarkus.http.auth.permission.authenticated
权限已设置,以告知 Quarkus 您要保护的路径。 在这种情况下,所有路径都受到策略的保护,该策略确保只有 authenticated
用户才能访问它们。 有关更多信息,请参阅安全授权指南。
当您不使用
建议加密密钥的长度为 32 个字符。 例如, |
4. 启动并配置 Keycloak 服务器
要启动 Keycloak 服务器,请使用 Docker 并运行以下命令
docker run --name keycloak -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
其中 keycloak.version
设置为 26.2.4
或更高版本。
您可以在 localhost:8180 访问您的 Keycloak 服务器。
要访问 Keycloak 管理控制台,请以 admin
用户身份登录。 用户名和密码均为 admin
。
5. 在开发和 JVM 模式下运行应用程序
要在开发模式下运行应用程序,请使用
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
在开发模式下探索完应用程序后,您可以将其作为标准的 Java 应用程序运行。
首先,编译它
quarkus build
./mvnw install
./gradlew build
然后,运行它
java -jar target/quarkus-app/quarkus-run.jar
6. 在 Native 模式下运行应用程序
此演示也可以编译为本机代码。 无需修改。
这意味着您不再需要在生产环境中安装 JVM,因为运行时技术包含在生成的二进制文件中,并且经过优化以最小的资源运行。
编译需要更长的时间,因此默认情况下禁用此步骤。 您可以通过启用本机构建再次构建
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true
稍后,您可以直接运行此二进制文件
./target/security-openid-connect-web-authentication-quickstart-runner
7. 测试应用程序
要测试应用程序,请打开浏览器并访问以下 URL
如果一切按预期工作,您将被重定向到 Keycloak 服务器进行身份验证。
要对应用程序进行身份验证,请在 Keycloak 登录页面上输入以下凭据
-
用户名:alice
-
密码:alice
单击 Login
按钮后,您将被重定向回应用程序,并且将创建一个会话 Cookie。
此演示的会话有效期很短,并且每次页面刷新时,您都会被要求重新进行身份验证。 有关如何增加会话超时的信息,请参阅 Keycloak 会话超时文档。 例如,如果您在开发模式下使用 Keycloak 的开发服务,则可以通过单击 Keycloak Admin
链接直接从开发 UI 访问 Keycloak 管理控制台

有关编写依赖于 Dev Services for Keycloak
的集成测试的更多信息,请参阅 Dev Services for Keycloak 部分。
总结
您已经学习了如何设置和使用 OIDC 授权码流程机制来保护和测试应用程序 HTTP 端点。 完成本教程后,请探索 OIDC Bearer 令牌身份验证和其他身份验证机制。