Skip to content

Commit

Permalink
docs,tests(oidc): Use OidcTestClient with Dev Svc for OIDC
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik committed Jan 16, 2025
1 parent beee3db commit e227b9c
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, <<dev-services-for-keycloak>> provides the best dev mode experience.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ public interface OidcDevServicesConfig {
/**
* A map of roles for OIDC identity provider users.
* <p>
* 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<String, List<String>> roles();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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<String> 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<String> getUsers() {
if (userToDefaultRoles.isEmpty()) {
return Arrays.asList("alice", "bob");
Expand Down
5 changes: 5 additions & 0 deletions integration-tests/oidc-dev-services/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-oidc-server</artifactId>
<scope>test</scope>
</dependency>
<!-- Minimal test dependencies to *-deployment artifacts for consistent build order -->
<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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);
Expand Down Expand Up @@ -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);
}
}

0 comments on commit e227b9c

Please sign in to comment.