Skip to content

Commit

Permalink
Merge pull request #44837 from sberyozkin/fix_oidc_testing_toc
Browse files Browse the repository at this point in the history
Show the OIDC testing with devservice section first
  • Loading branch information
sberyozkin authored Dec 2, 2024
2 parents 21e2179 + 138f4b2 commit ae27925
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 130 deletions.
191 changes: 96 additions & 95 deletions docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,101 @@ testImplementation("io.rest-assured:rest-assured")
testImplementation("io.quarkus:quarkus-junit5")
----

[[bearer-token-integration-testing-keycloak-devservices]]
==== Dev Services for Keycloak

The preferred approach for integration testing against Keycloak is xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak].
`Dev Services for Keycloak` will start and initialize a test container.
Then, it will create a `quarkus` realm and a `quarkus-app` client (`secret` secret) and add `alice` (`admin` and `user` roles) and `bob` (`user` role) users, where all of these properties can be customized.

First, add the following dependency, which provides a utility class `io.quarkus.test.keycloak.client.KeycloakTestClient` that you can use in tests for acquiring the access tokens:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-keycloak-server</artifactId>
<scope>test</scope>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
testImplementation("io.quarkus:quarkus-test-keycloak-server")
----

Next, prepare your `application.properties` configuration file.
You can start with an empty `application.properties` file because `Dev Services for Keycloak` registers `quarkus.oidc.auth-server-url` and points it to the running test container, `quarkus.oidc.client-id=quarkus-app`, and `quarkus.oidc.credentials.secret=secret`.

However, if you have already configured the required `quarkus-oidc` properties, then you only need to associate `quarkus.oidc.auth-server-url` with the `prod` profile for `Dev Services for Keycloak`to start a container, as shown in the following example:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
----

If a custom realm file has to be imported into Keycloak before running the tests, configure `Dev Services for Keycloak` as follows:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.keycloak.devservices.realm-path=quarkus-realm.json
----

Finally, write your test, which will be executed in JVM mode, as shown in the following examples:

.Example of a test executed in JVM mode:

[source,java]
----
package org.acme.security.openid.connect;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.keycloak.client.KeycloakTestClient;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
@QuarkusTest
public class BearerTokenAuthenticationTest {
KeycloakTestClient keycloakClient = new KeycloakTestClient();
@Test
public void testAdminAccess() {
RestAssured.given().auth().oauth2(getAccessToken("alice"))
.when().get("/api/admin")
.then()
.statusCode(200);
RestAssured.given().auth().oauth2(getAccessToken("bob"))
.when().get("/api/admin")
.then()
.statusCode(403);
}
protected String getAccessToken(String userName) {
return keycloakClient.getAccessToken(userName);
}
}
----

.Example of a test executed in native mode:

[source,java]
----
package org.acme.security.openid.connect;
import io.quarkus.test.junit.QuarkusIntegrationTest;
@QuarkusIntegrationTest
public class NativeBearerTokenAuthenticationIT extends BearerTokenAuthenticationTest {
}
----

For more information about initializing and configuring Dev Services for Keycloak, see the xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] guide.


[[bearer-token-integration-testing-wiremock]]
==== WireMock

Expand Down Expand Up @@ -697,7 +792,7 @@ public class CustomOidcWireMockStubTest {
----

[[integration-testing-oidc-test-client]]
=== `OidcTestClient`
==== `OidcTestClient`

If you use SaaS OIDC providers, such as `Auth0`, and want to run tests against the test (development) domain or to run tests against a remote Keycloak test realm, if you already have `quarkus.oidc.auth-server-url` configured, you can use `OidcTestClient`.

Expand Down Expand Up @@ -762,100 +857,6 @@ 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.

[[bearer-token-integration-testing-keycloak-devservices]]
==== Dev Services for Keycloak

The preferred approach for integration testing against Keycloak is xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak].
`Dev Services for Keycloak` will start and initialize a test container.
Then, it will create a `quarkus` realm and a `quarkus-app` client (`secret` secret) and add `alice` (`admin` and `user` roles) and `bob` (`user` role) users, where all of these properties can be customized.

First, add the following dependency, which provides a utility class `io.quarkus.test.keycloak.client.KeycloakTestClient` that you can use in tests for acquiring the access tokens:

[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
.pom.xml
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-keycloak-server</artifactId>
<scope>test</scope>
</dependency>
----

[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
.build.gradle
----
testImplementation("io.quarkus:quarkus-test-keycloak-server")
----

Next, prepare your `application.properties` configuration file.
You can start with an empty `application.properties` file because `Dev Services for Keycloak` registers `quarkus.oidc.auth-server-url` and points it to the running test container, `quarkus.oidc.client-id=quarkus-app`, and `quarkus.oidc.credentials.secret=secret`.

However, if you have already configured the required `quarkus-oidc` properties, then you only need to associate `quarkus.oidc.auth-server-url` with the `prod` profile for `Dev Services for Keycloak`to start a container, as shown in the following example:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
----

If a custom realm file has to be imported into Keycloak before running the tests, configure `Dev Services for Keycloak` as follows:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.keycloak.devservices.realm-path=quarkus-realm.json
----

Finally, write your test, which will be executed in JVM mode, as shown in the following examples:

.Example of a test executed in JVM mode:

[source,java]
----
package org.acme.security.openid.connect;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.keycloak.client.KeycloakTestClient;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
@QuarkusTest
public class BearerTokenAuthenticationTest {
KeycloakTestClient keycloakClient = new KeycloakTestClient();
@Test
public void testAdminAccess() {
RestAssured.given().auth().oauth2(getAccessToken("alice"))
.when().get("/api/admin")
.then()
.statusCode(200);
RestAssured.given().auth().oauth2(getAccessToken("bob"))
.when().get("/api/admin")
.then()
.statusCode(403);
}
protected String getAccessToken(String userName) {
return keycloakClient.getAccessToken(userName);
}
}
----

.Example of a test executed in native mode:

[source,java]
----
package org.acme.security.openid.connect;
import io.quarkus.test.junit.QuarkusIntegrationTest;
@QuarkusIntegrationTest
public class NativeBearerTokenAuthenticationIT extends BearerTokenAuthenticationTest {
}
----

For more information about initializing and configuring Dev Services for Keycloak, see the xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] guide.

ifndef::no-deprecated-test-resource[]
[[bearer-token-integration-testing-keycloak]]
==== `KeycloakTestResourceLifecycleManager`
Expand Down
78 changes: 43 additions & 35 deletions docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,49 @@ testImplementation("org.htmlunit:htmlunit")
testImplementation("io.quarkus:quarkus-junit5")
----

[[code-flow-integration-testing-keycloak-devservices]]
=== Dev Services for Keycloak

For integration testing against Keycloak, use xref:security-openid-connect-dev-services.adoc[Dev services for Keycloak].
This service initializes a test container, creates a `quarkus` realm, and configures a `quarkus-app` client with the secret `secret`.
It also sets up two users: `alice` with `admin` and `user` roles, and `bob` with the `user` role.
All these properties are customizable. For details, see xref:security-openid-connect-dev-services.adoc#keycloak-initialization[Keycloak Initialization].

First, prepare the `application.properties` file.

If starting from an empty `application.properties` file, `Dev Services for Keycloak` automatically registers the following properties:

- `quarkus.oidc.auth-server-url`, which points to the running test container.
- `quarkus.oidc.client-id=quarkus-app`.
- `quarkus.oidc.credentials.secret=secret`.

If you already have the required `quarkus-oidc` properties configured, associate `quarkus.oidc.auth-server-url` with the `prod` profile.
This ensures that `Dev Services for Keycloak` starts the container as expected.
For example:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
----

To import a custom realm file into Keycloak before running the tests, configure `Dev services for Keycloak` as shown:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.keycloak.devservices.realm-path=quarkus-realm.json
----

Finally, write the test code as described in the <<code-flow-integration-testing-wiremock,Wiremock>> section.
The only difference is that `@QuarkusTestResource` is no longer required:

[source, java]
----
@QuarkusTest
public class CodeFlowAuthorizationTest {
}
----

[[code-flow-integration-testing-wiremock]]
=== Wiremock

Expand Down Expand Up @@ -1897,41 +1940,6 @@ Additionally, `OidcWiremockTestResource` sets the token issuer and audience to `

`OidcWiremockTestResource` can be used to emulate all OIDC providers.

[[code-flow-integration-testing-keycloak-devservices]]
=== Dev Services for Keycloak

Using xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] is recommended for integration testing against Keycloak.
`Dev Services for Keycloak` will start and initialize a test container: it will create a `quarkus` realm, a `quarkus-app` client (`secret` secret), and add `alice` (`admin` and `user` roles) and `bob` (`user` role) users, where all of these properties can be customized.

First, prepare `application.properties`.
You can start with a completely empty `application.properties` file as `Dev Services for Keycloak` will register `quarkus.oidc.auth-server-url` pointing to the running test container as well as `quarkus.oidc.client-id=quarkus-app` and `quarkus.oidc.credentials.secret=secret`.

However, if you already have all the required `quarkus-oidc` properties configured, then you only need to associate `quarkus.oidc.auth-server-url` with the `prod` profile for `Dev Services for Keycloak` to start a container.
For example:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
----

If a custom realm file has to be imported into Keycloak before running the tests, then you can configure `Dev Services for Keycloak` as follows:

[source,properties]
----
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.keycloak.devservices.realm-path=quarkus-realm.json
----

Finally, write a test code the same way as it is described in the <<code-flow-integration-testing-wiremock,Wiremock>> section.
The only difference is that `@QuarkusTestResource` is no longer needed:

[source, java]
----
@QuarkusTest
public class CodeFlowAuthorizationTest {
}
----

ifndef::no-deprecated-test-resource[]
[[code-flow-integration-testing-keycloak]]
=== Using KeycloakTestResourceLifecycleManager
Expand Down

0 comments on commit ae27925

Please sign in to comment.