use of io.vertx.ext.web.handler.WebAuthnHandler in project vertx-web by vert-x3.
the class AuthenticatorStore method testServerForFIDO2TCK.
@Test(timeout = 300_000)
@Ignore("This test needs to be executed manually against the Conformance Tools")
public void testServerForFIDO2TCK(TestContext should) {
final Async test = should.async();
final Vertx vertx = rule.vertx();
final FileSystem fs = vertx.fileSystem();
// clear the DB at each run to avoid previous state
database.clear();
final WebAuthnOptions config = new WebAuthnOptions().setRelyingParty(new RelyingParty().setName("Vert.x Conformance Test 4.2.0")).putRootCertificate("mds", MDS3_ROOT_CERTIFICATE).addRootCrl(MDS3_MDSCA_1_CRL);
// create the webauthn security object
WebAuthn webAuthN = WebAuthn.create(vertx, config).authenticatorFetcher(database::fetcher).authenticatorUpdater(database::updater);
// do we want to load custom metadata statements?
if (fs.existsBlocking("metadataStatements")) {
for (String f : fs.readDirBlocking("metadataStatements")) {
System.out.println("Loading metadata statement: " + f);
webAuthN.metaDataService().addStatement(new JsonObject(fs.readFileBlocking(f)));
}
} else {
should.fail("test metadata statements are not in the filesystem!");
return;
}
List<Future> futures = new ArrayList<>();
// do we want to load custom MDS3 servers?
for (String el : MDS3) {
System.out.println("Loading toc: " + el);
futures.add(webAuthN.metaDataService().fetchTOC(el));
}
CompositeFuture.all(futures).onFailure(should::fail).onSuccess(done -> {
final Router app = Router.router(vertx);
// parse the BODY
app.post().handler(BodyHandler.create());
// add a session handler
app.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));
app.post("/attestation/options").handler(ctx -> {
JsonObject json = ctx.getBodyAsJson();
// vert.x doesn't work with "username" but "name"
if (json.containsKey("username")) {
String username = json.getString("username");
json.remove("username");
json.put("name", username);
// patch the request
ctx.setBody(json.toBuffer());
}
// register, we need to listen to the request and change the config
JsonObject authenticatorSelection = json.getJsonObject("authenticatorSelection");
if (authenticatorSelection != null) {
if (authenticatorSelection.containsKey("requireResidentKey")) {
config.setRequireResidentKey(authenticatorSelection.getBoolean("requireResidentKey"));
}
if (authenticatorSelection.containsKey("authenticatorAttachment")) {
config.setAuthenticatorAttachment(AuthenticatorAttachment.of(authenticatorSelection.getString("authenticatorAttachment")));
}
if (authenticatorSelection.containsKey("userVerification")) {
config.setUserVerification(UserVerification.of(authenticatorSelection.getString("userVerification")));
}
}
config.setAttestation(Attestation.of(json.getString("attestation")));
config.setExtensions(json.getJsonObject("extensions"));
ctx.next();
});
app.post("/attestation/result").handler(ctx -> {
ctx.reroute("/callback");
});
app.post("/assertion/options").handler(ctx -> {
JsonObject json = ctx.getBodyAsJson();
// vert.x doesn't work with "username" but "name"
if (json.containsKey("username")) {
String username = json.getString("username");
json.remove("username");
json.put("name", username);
// patch the request
ctx.setBody(json.toBuffer());
}
config.setUserVerification(UserVerification.of(json.getString("userVerification", "discouraged")));
config.setExtensions(json.getJsonObject("extensions"));
ctx.next();
});
app.post("/assertion/result").handler(ctx -> {
ctx.reroute("/callback");
});
// security handler
WebAuthnHandler webAuthnHandler = WebAuthnHandler.create(webAuthN).setOrigin(ORIGIN).setupCallback(app.post("/callback")).setupCredentialsCreateCallback(app.post("/attestation/options")).setupCredentialsGetCallback(app.post("/assertion/options"));
// secure the remaining routes
app.route().handler(webAuthnHandler);
// failure handler to comply to conformance test requirements
app.route().failureHandler(ctx -> {
ctx.failure().printStackTrace();
ctx.response().setStatusCode(500);
ctx.json(new JsonObject().put("status", "failed").put("errorMessage", ctx.failure().getMessage()));
});
vertx.createHttpServer().requestHandler(app).listen(8080, "0.0.0.0").onFailure(should::fail).onSuccess(v -> {
System.out.printf("Server listening at: %s%n", ORIGIN);
System.out.println("-----------------------------------");
System.out.println("Run the FIDO2 Conformance tool now!");
System.out.println("-----------------------------------");
});
});
}
Aggregations