Protect a web application by using OpenID Connect (OIDC) authorization code flow
使用 Quarkus OIDC 扩展了解如何通过使用 Quarkus OIDC 的授权代码流程机制保护应用程序 HTTP 端点,从而提供强大的身份验证和授权。 有关更多信息,请参见 OIDC code flow mechanism for protecting web applications。 要了解如何将众所周知的社交提供商(例如 Apple、Facebook、GitHub、Google、Mastodon、Microsoft、Spotify、Twitch 和 X(以前的 Twitter)与 Quarkus OIDC 配合使用,请参见 Configuring well-known OpenID Connect providers。另外请参见 Authentication mechanisms in Quarkus。 如果您想通过使用 OIDC Bearer 令牌身份验证来保护您的服务应用程序,请参见 OIDC Bearer token authentication。
Prerequisites
如要完成本指南,您需要:
-
Roughly 15 minutes
-
An IDE
-
安装了 JDK 17+,已正确配置
JAVA_HOME
-
Apache Maven ${proposed-maven-version}
-
如果你想使用 Quarkus CLI, 则可以选择使用
-
如果你想构建一个本机可执行文件(或如果你使用本机容器构建,则使用 Docker),则可以选择安装 Mandrel 或 GraalVM 以及 configured appropriately
Solution
按照以下各节中的说明,按步骤创建应用。或者您可以直接转到已完成示例。
通过运行 git clone $${quickstarts-base-url}.git
命令克隆 Git 存储库。或者下载一个 $${quickstarts-base-url}/archive/main.zip[存档]。
该解决方案位于 security-openid-connect-web-authentication-quickstart
directory。
Create the Maven project
首先,我们需要一个新项目。通过运行以下命令创建一个新项目:
quarkus create app {create-app-group-id}:{create-app-artifact-id} \
--no-code
cd {create-app-artifact-id}
要创建一个 Gradle 项目,添加 --gradle
或 --gradle-kotlin-dsl
选项。
有关如何安装和使用 Quarkus CLI 的详细信息,请参见 Quarkus CLI 指南。
mvn {quarkus-platform-groupid}:quarkus-maven-plugin:{quarkus-version}:create \
-DprojectGroupId={create-app-group-id} \
-DprojectArtifactId={create-app-artifact-id} \
-DnoCode
cd {create-app-artifact-id}
要创建一个 Gradle 项目,添加 -DbuildTool=gradle
或 -DbuildTool=gradle-kotlin-dsl
选项。
适用于 Windows 用户:
-
如果使用 cmd,(不要使用反斜杠
\
,并将所有内容放在同一行上) -
如果使用 Powershell,将
-D
参数用双引号引起来,例如"-DprojectArtifactId={create-app-artifact-id}"
如果你的 Quarkus 项目已经配置好,你可以通过在项目基础目录中运行以下命令将 oidc
扩展名添加到项目:
quarkus extension add {add-extension-extensions}
./mvnw quarkus:add-extension -Dextensions='{add-extension-extensions}'
./gradlew addExtension --extensions='{add-extension-extensions}'
这会将以下依赖关系添加到您的构建文件中:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
</dependency>
implementation("io.quarkus:quarkus-oidc")
Write the application
让我们编写一个简单的 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 令牌与当前经过身份验证的用户进行交互或使用访问令牌代表此用户访问下游服务时,才需要注入令牌。
有关更多信息,请参阅参考指南的 Access ID and Access Tokens 部分。
Configure the application
OIDC 扩展允许您使用 src/main/resources
目录中的 application.properties
文件定义配置。
quarkus.oidc.auth-server-url=http://localhost: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
用户才能访问它们。有关更多信息,请参阅 Security Authorization Guide。
当您不使用 |
Start and configure the Keycloak server
要启动 Keycloak 服务器,请使用 Docker 并运行以下命令:
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
在其中 keycloak.version
设置为 25.0.2
或更高版本。
您可以在 localhost:8180 访问您的 Keycloak 服务器。
要访问 Keycloak 管理控制台,请使用 admin
用户登录。用户名和密码均为 admin
。
要创建新的领域,导入 realm configuration file。有关详细信息,请参阅 Keycloak 文档,了解如何 create and configure a new realm。
Run the application in dev and JVM modes
要以 dev 模式运行应用程序,请使用:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
在 dev 模式下探索应用程序后,您可以将其作为标准 Java 应用程序运行。
首先,对其进行编译:
quarkus build
./mvnw install
./gradlew build
然后,运行它:
java -jar target/quarkus-app/quarkus-run.jar
Run the application in Native mode
可以将此相同演示编译为本机代码。无需任何修改。
这意味着您无需在生产环境中安装 JVM,因为运行时技术包含在生成的可执行文件中,并经过优化,可使用最少资源运行。
编译需要更长时间,因此默认情况下此步骤已关闭。您可以通过启用本机构建来重新构建:
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true
一段时间后,您可以直接运行此二进制文件:
./target/security-openid-connect-web-authentication-quickstart-runner
Test the application
要测试应用程序,请打开浏览器并访问以下 URL:
如果所有内容按预期工作,您将被重定向到 Keycloak 服务器进行身份验证。
要对该应用程序进行身份验证,请在 Keycloak 登录页面输入以下凭据:
-
Username: alice
-
Password: alice
单击 Login
按钮后,您将被重定向回该应用程序,并且将创建会话 Cookie。
此演示的会话有效期很短,并且在每次刷新页面时,系统都会要求您重新进行身份验证。有关如何增加会话超时时间的详细信息,请参阅 Keycloak session timeout 文档。例如,如果您在开发模式中使用 Dev Services for Keycloak,则可以从开发 UI 中通过单击 Keycloak Admin
链接直接访问 Keycloak Admin 控制台:
有关编写依赖于 Dev Services for Keycloak
的集成测试的详细信息,请参阅 Dev Services for Keycloak 部分。
Summary
您已经了解如何设置和使用 OIDC 授权代码流机制来保护和测试应用程序 HTTP 端点。完成本教程后,浏览 OIDC Bearer token authentication和 other authentication mechanisms。