diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc index 1e5bc86d05267..0e3c6a1bfe588 100644 --- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc +++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc @@ -857,6 +857,48 @@ For a test like this to work, the test `Auth0` application must have the `passwo This example code also shows how to pass additional parameters. For `Auth0`, these are the `audience` and `scope` parameters. +===== Test OIDC DevService + +You can also use `OidcTestClient` to test Quarkus endpoints supported by xref:security-openid-connect-dev-services.adoc#dev-services-for-oidc[Dev Services for OIDC]. +No configuration in the `application.properties` file is needed, Quarkus will configure `OidcTestClient` for you: + +[source, java] +---- +package org.acme; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.oidc.client.OidcTestClient; + +@QuarkusTest +public class GreetingResourceTest { + + static final OidcTestClient oidcTestClient = new OidcTestClient(); + + @AfterAll + public static void close() { + oidcTestClient.close(); + } + + @Test + public void testHelloEndpoint() { + String accessToken = oidcTestClient.getAccessToken("alice", "alice"); + given() + .auth().oauth2(accessToken) + .when().get("/hello") + .then() + .statusCode(200) + .body(is("Hello, Alice")); + } + +} +---- + ifndef::no-deprecated-test-resource[] [[bearer-token-integration-testing-keycloak]] ==== `KeycloakTestResourceLifecycleManager` diff --git a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc index 538f7c1b7e040..5bfb9256f947b 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -380,6 +380,7 @@ This document refers to the `http://localhost:8080/q/dev-ui` Dev UI URL in sever If you customize `quarkus.http.root-path` or `quarkus.http.non-application-root-path` properties, then replace `q` accordingly. For more information, see the https://quarkus.io/blog/path-resolution-in-quarkus/[Path resolution in Quarkus] blog post. +[[dev-services-for-oidc]] == Dev Services for OIDC When you work with Keycloak in production, <> provides the best dev mode experience. diff --git a/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesConfig.java b/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesConfig.java index e97eef86dad8d..e1adb8178adb7 100644 --- a/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesConfig.java +++ b/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesConfig.java @@ -25,9 +25,7 @@ public interface OidcDevServicesConfig { /** * A map of roles for OIDC identity provider users. *

- * If empty, default roles are assigned: `alice` receives `admin` and `user` roles, while other users receive - * `user` role. - * This map is used for role creation when no realm file is found at the `realm-path`. + * If empty, default roles are assigned: user `alice` receives `admin` and `user` roles and user `bob` receives role `user`. */ @ConfigDocMapKey("role-name") Map> roles(); diff --git a/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesProcessor.java b/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesProcessor.java index 1729e3ad64e70..1e03ae0158540 100644 --- a/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesProcessor.java +++ b/extensions/devservices/oidc/src/main/java/io/quarkus/devservices/oidc/OidcDevServicesProcessor.java @@ -192,9 +192,6 @@ private static void registerRoutes(Router router) { router.get("/logout").handler(OidcDevServicesProcessor::logout); router.get("/userinfo").handler(OidcDevServicesProcessor::userInfo); - // can be used for testing of bearer token authentication - router.get("/testing/generate/access-token").handler(OidcDevServicesProcessor::generateAccessToken); - KeyPairGenerator kpg; try { kpg = KeyPairGenerator.getInstance("RSA"); @@ -206,22 +203,6 @@ private static void registerRoutes(Router router) { kid = createKeyId(); } - private static void generateAccessToken(RoutingContext rc) { - String user = rc.request().getParam("user"); - if (user == null || user.isEmpty()) { - rc.response().setStatusCode(400).endAndForget("Missing required parameter: user"); - return; - } - String rolesParam = rc.request().getParam("roles"); - Set roles = new HashSet<>(); - if (rolesParam == null || rolesParam.isEmpty()) { - roles.addAll(getUserRoles(user)); - } else { - roles.addAll(Arrays.asList(rolesParam.split(","))); - } - rc.response().endAndForget(createAccessToken(user, roles, Set.of("openid", "email"))); - } - private static List getUsers() { if (userToDefaultRoles.isEmpty()) { return Arrays.asList("alice", "bob"); diff --git a/integration-tests/oidc-dev-services/pom.xml b/integration-tests/oidc-dev-services/pom.xml index eace1af7f7741..50458d925f246 100644 --- a/integration-tests/oidc-dev-services/pom.xml +++ b/integration-tests/oidc-dev-services/pom.xml @@ -44,6 +44,11 @@ + + io.quarkus + quarkus-test-oidc-server + test + io.quarkus diff --git a/integration-tests/oidc-dev-services/src/main/resources/application.properties b/integration-tests/oidc-dev-services/src/main/resources/application.properties index 636d87caec1ef..02f7a3cbb7aa3 100644 --- a/integration-tests/oidc-dev-services/src/main/resources/application.properties +++ b/integration-tests/oidc-dev-services/src/main/resources/application.properties @@ -1,3 +1,6 @@ quarkus.oidc.devservices.enabled=true +quarkus.oidc.devservices.roles.Ronald=admin +%code-flow.quarkus.oidc.devservices.roles.alice=admin,user +%code-flow.quarkus.oidc.devservices.roles.bob=user %code-flow.quarkus.oidc.application-type=web-app diff --git a/integration-tests/oidc-dev-services/src/test/java/io/quarkus/it/oidc/dev/services/BearerAuthenticationOidcDevServicesTest.java b/integration-tests/oidc-dev-services/src/test/java/io/quarkus/it/oidc/dev/services/BearerAuthenticationOidcDevServicesTest.java index eac0592af5e07..623c51403e732 100644 --- a/integration-tests/oidc-dev-services/src/test/java/io/quarkus/it/oidc/dev/services/BearerAuthenticationOidcDevServicesTest.java +++ b/integration-tests/oidc-dev-services/src/test/java/io/quarkus/it/oidc/dev/services/BearerAuthenticationOidcDevServicesTest.java @@ -1,25 +1,34 @@ package io.quarkus.it.oidc.dev.services; import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.oidc.client.OidcTestClient; import io.restassured.RestAssured; @QuarkusTest public class BearerAuthenticationOidcDevServicesTest { + static final OidcTestClient oidcTestClient = new OidcTestClient(); + + @AfterAll + public static void close() { + oidcTestClient.close(); + } + @Test public void testLoginAsCustomUser() { RestAssured.given() - .auth().oauth2(getAccessToken("Ronald", "admin")) + .auth().oauth2(getAccessToken("Ronald")) .get("/secured/admin-only") .then() .statusCode(200) .body(Matchers.containsString("Ronald")) .body(Matchers.containsString("admin")); RestAssured.given() - .auth().oauth2(getAccessToken("Ronald", "admin")) + .auth().oauth2(getAccessToken("Ronald")) .get("/secured/user-only") .then() .statusCode(403); @@ -62,16 +71,6 @@ public void testLoginAsBob() { } private String getAccessToken(String user) { - return RestAssured.given().get(getAuthServerUrl() + "/testing/generate/access-token?user=" + user).asString(); - } - - private String getAccessToken(String user, String... roles) { - return RestAssured.given() - .get(getAuthServerUrl() + "/testing/generate/access-token?user=" + user + "&roles=" + String.join(",", roles)) - .asString(); - } - - private static String getAuthServerUrl() { - return RestAssured.get("/secured/auth-server-url").then().statusCode(200).extract().body().asString(); + return oidcTestClient.getAccessToken(user, user); } }