package io.vertx.ext.auth.oauth2.providers;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.oauth2.OAuth2Auth;
import io.vertx.ext.auth.oauth2.OAuth2ClientOptions;
import io.vertx.ext.auth.oauth2.OAuth2Response;
import static io.vertx.ext.auth.oauth2.impl.OAuth2API.*;
@VertxGen
public interface OpenIDConnectAuth {
static void discover(final Vertx vertx, final OAuth2ClientOptions config, final Handler<AsyncResult<OAuth2Auth>> handler) {
if (config.getSite() == null) {
handler.handle(Future.failedFuture("issuer cannot be null"));
return;
}
final HttpClientRequest request = makeRequest(vertx, config, HttpMethod.GET, config.getSite() + "/.well-known/openid-configuration", res -> {
if (res.failed()) {
handler.handle(Future.failedFuture(res.cause()));
return;
}
final OAuth2Response response = res.result();
if (response.statusCode() != 200) {
handler.handle(Future.failedFuture("Bad Response [" + response.statusCode() + "] " + response.body()));
return;
}
if (!response.is("application/json")) {
handler.handle(Future.failedFuture("Cannot handle Content-Type: " + response.headers().get("Content-Type")));
return;
}
final JsonObject json = response.jsonObject();
if (config.isValidateIssuer()) {
final String issuerEndpoint = json.getString("issuer");
if (issuerEndpoint != null && !config.getSite().equals(issuerEndpoint)) {
handler.handle(Future.failedFuture("issuer validation failed: received [" + issuerEndpoint + "]"));
return;
}
}
config.setAuthorizationPath(json.getString("authorization_endpoint"));
config.setTokenPath(json.getString("token_endpoint"));
config.setIntrospectionPath(json.getString("token_introspection_endpoint"));
config.setLogoutPath(json.getString("end_session_endpoint"));
config.setRevocationPath(json.getString("revocation_endpoint"));
config.setUserInfoPath(json.getString("userinfo_endpoint"));
config.setJwkPath(json.getString("jwks_uri"));
final OAuth2Auth oidc = OAuth2Auth.create(vertx, config);
if (config.getJwkPath() != null) {
oidc.loadJWK(v -> {
if (v.failed()) {
handler.handle(Future.failedFuture(v.cause()));
return;
}
handler.handle(Future.succeededFuture(oidc));
});
} else {
handler.handle(Future.succeededFuture(oidc));
}
});
request.exceptionHandler(t -> handler.handle(Future.failedFuture(t)));
request.putHeader("Accept", "application/json");
request.end();
}
}