96 lines
3.5 KiB
Java
Executable file
96 lines
3.5 KiB
Java
Executable file
package de.pzzz.vertx.oauth;
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
import io.vertx.core.Future;
|
|
import io.vertx.core.MultiMap;
|
|
import io.vertx.core.Promise;
|
|
import io.vertx.core.Vertx;
|
|
import io.vertx.core.buffer.Buffer;
|
|
import io.vertx.core.http.HttpMethod;
|
|
import io.vertx.ext.web.client.HttpRequest;
|
|
import io.vertx.ext.web.client.WebClient;
|
|
import io.vertx.ext.web.client.WebClientOptions;
|
|
import io.vertx.ext.web.codec.BodyCodec;
|
|
|
|
public class OAuthWebClient {
|
|
private static final Logger LOG = Logger.getLogger(OAuthWebClient.class.getName());
|
|
|
|
private final WebClient webClient;
|
|
private final OAuthConfig config;
|
|
private OAuthToken token;
|
|
|
|
public OAuthWebClient(final Vertx vertx, final OAuthConfig config) {
|
|
this.webClient = WebClient.create(vertx, new WebClientOptions()
|
|
.setLogActivity(true).setSsl(true).setTrustAll(config.isTrustAllCertificates()).setVerifyHost(false));
|
|
this.config = config;
|
|
}
|
|
|
|
public Future<HttpRequest<Buffer>> prepareAuthenticatedPut(final String requestPath) {
|
|
return prepareAuthenticatedRequest(HttpMethod.PUT, requestPath);
|
|
}
|
|
|
|
public Future<HttpRequest<Buffer>> prepareAuthenticatedGet(final String requestPath) {
|
|
return prepareAuthenticatedRequest(HttpMethod.GET, requestPath);
|
|
}
|
|
|
|
public Future<HttpRequest<Buffer>> prepareAuthenticatedPost(final String requestPath) {
|
|
return prepareAuthenticatedRequest(HttpMethod.POST, requestPath);
|
|
}
|
|
|
|
public Future<HttpRequest<Buffer>> prepareAuthenticatedDelete(final String requestPath) {
|
|
return prepareAuthenticatedRequest(HttpMethod.DELETE, requestPath);
|
|
}
|
|
|
|
public Future<HttpRequest<Buffer>> prepareAuthenticatedRequest(final HttpMethod method, final String requestPath) {
|
|
Promise<HttpRequest<Buffer>> promise = Promise.promise();
|
|
ensureIsAuthenticated().andThen(v ->
|
|
promise.complete(webClient.requestAbs(method, config.getBaseUrl() + requestPath)
|
|
.bearerTokenAuthentication(token.getToken()))
|
|
).onFailure(promise::fail);
|
|
return promise.future();
|
|
}
|
|
|
|
private Future<Void> ensureIsAuthenticated() {
|
|
if (null != token && token.isValid()) {
|
|
LOG.finest("keeping token...");
|
|
return Future.succeededFuture();
|
|
}
|
|
LOG.finest("Requesting new token...");
|
|
return getToken();
|
|
}
|
|
|
|
private Future<Void> getToken() {
|
|
String baseErrorMessage = "Failed to login! ";
|
|
Promise<Void> promise = Promise.promise();
|
|
MultiMap form = MultiMap.caseInsensitiveMultiMap();
|
|
form.set("grant_type", "client_credentials");
|
|
LOG.fine("Requesting new token...");
|
|
webClient.postAbs(config.getOauthTokenUrl())
|
|
.basicAuthentication(config.getOauthClientId(), config.getOauthClientSecret())
|
|
.as(BodyCodec.json(OAuthToken.class))
|
|
.sendForm(form)
|
|
.onSuccess(response -> {
|
|
if (response.statusCode() == 200) {
|
|
token = response.body();
|
|
LOG.finest("Got new token...");
|
|
promise.complete();
|
|
} else {
|
|
String errorMessage = baseErrorMessage + response.statusCode() + " - "
|
|
+ response.statusMessage();
|
|
handleTokenError(errorMessage, promise);
|
|
}
|
|
})
|
|
.onFailure(error -> {
|
|
String errorMessage = baseErrorMessage + error.getMessage();
|
|
handleTokenError(errorMessage, promise);
|
|
});
|
|
return promise.future();
|
|
}
|
|
|
|
private void handleTokenError(final String errorMessage, final Promise<Void> promise) {
|
|
LOG.severe(errorMessage);
|
|
token = null;
|
|
promise.fail(errorMessage);
|
|
}
|
|
}
|