Skip to content

Commit

Permalink
Merge pull request #462 from vert-x3/oauth-aware-web-client
Browse files Browse the repository at this point in the history
Added examples for OAuth2WebClient
  • Loading branch information
vietj authored Oct 30, 2024
2 parents 3b955fb + dfe0fca commit 8f970c3
Show file tree
Hide file tree
Showing 3 changed files with 2,189 additions and 0 deletions.
16 changes: 16 additions & 0 deletions web-client-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@
<artifactId>vertx-web-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-oauth2</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.20.3</version>
</dependency>

</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package io.vertx.example.webclient.oauth;

import io.vertx.core.Future;
import io.vertx.core.VerticleBase;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.auth.oauth2.OAuth2FlowType;
import io.vertx.ext.auth.oauth2.OAuth2Options;
import io.vertx.ext.auth.oauth2.Oauth2Credentials;
import io.vertx.ext.auth.oauth2.providers.KeycloakAuth;
import io.vertx.ext.web.client.OAuth2WebClient;
import io.vertx.ext.web.client.OAuth2WebClientOptions;
import io.vertx.ext.web.client.WebClient;
import io.vertx.launcher.application.VertxApplication;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;

/**
* @author <a href="mailto:lazarbulic@gmail.com">Lazar Bulic</a>
*/
public class OAuthAwareClientExample extends VerticleBase {

private static final String KEYCLOAK_IMAGE = "quay.io/keycloak/keycloak:26.0.2";

private static GenericContainer<?> keycloakContainerCustom;

public static void main(String[] args) {
keycloakContainerCustom = new GenericContainer<>(DockerImageName.parse(KEYCLOAK_IMAGE))
.withExposedPorts(8080)
.withCopyFileToContainer(MountableFile.forClasspathResource("/realm-export.json", 0644), "/opt/keycloak/data/import/realm-export.json")
.withCommand("start-dev", "--import-realm");

keycloakContainerCustom
.setWaitStrategy(Wait.forLogMessage(".*Running the server in development mode\\. DO NOT use this configuration in production.*\\n", 1));
keycloakContainerCustom.start();

VertxApplication.main(new String[]{OAuthAwareClientExample.class.getName()});
}

private OAuth2WebClient oAuth2WebClient;

@Override
public Future<?> start() throws Exception {
mockServer();

// Create base web client
WebClient client = WebClient.create(vertx);

// Discover Keycloak
return KeycloakAuth.discover(
vertx,
new OAuth2Options()
.setClientId("vertx-examples-client")
.setClientSecret("Bccl2MPUjEiLYaMSeTeZ30OesPxY4c1k")
.setSite("http://localhost:" + keycloakContainerCustom.getMappedPort(8080) + "/realms/{realm}")
.setTenant("vertx-examples"))
.onSuccess(keycloakAuth -> {

// Create OAuth2WebClient with Keycloak OAuth2 configuration
oAuth2WebClient = OAuth2WebClient.create(client, keycloakAuth,
new OAuth2WebClientOptions()
.setLeeway(5) //If a request is to be performed the current active user object is checked for expiration with the extra given leeway
.setRenewTokenOnForbidden(true)); // client will perform a new token request retry the original request before passing the response to the user handler/promise
})
.flatMap(ignore -> {

// Send request to protected resource with client_credentials flow
return oAuth2WebClient
.withCredentials(new Oauth2Credentials().setFlow(OAuth2FlowType.CLIENT))
.get(8081, "localhost", "protected/path")
.send()
.onSuccess(response -> {
System.out.println("Got HTTP response with status " + response.statusCode() + " from " + response.bodyAsString());
});
})
.flatMap(ignore -> {

// Send request to protected resource with password flow
return oAuth2WebClient
.withCredentials(new Oauth2Credentials().setFlow(OAuth2FlowType.PASSWORD)
.setUsername("janedoe")
.setPassword("s3cr3t"))
.get(8081, "localhost", "protected/path")
.send()
.onSuccess(response -> {
System.out.println("Got HTTP response with status " + response.statusCode() + " from " + response.bodyAsString());
});
});
}

public void mockServer() {
vertx.createHttpServer().requestHandler(req -> {
if (req.method() == HttpMethod.GET && "protected/path".equals(req.path())) {
String token = req.getHeader("Authorization");
if (token == null || token.isEmpty()) {
req.response().setStatusCode(401).end();
} else {
req.response().end("Protected resource");
}
} else {
req.response().end("Public resource");
}
}).listen(8081);
}
}
Loading

0 comments on commit 8f970c3

Please sign in to comment.