I want to add WebAuthN as an option for multi factor authentication to an Angular & Spring application. I use the WebAuthN java-webauthn-server library from Yubico.
What is the best way to integration test my WebAuthN server, without a hardware client? Is there any software that can handle the cryptography in an automated test? I want to run these tests automatically in the CI/CD pipeline (GitLab).
In a best case scenario I want to be able to test the whole process, creating credentials as well as logging in. An alternative scenario could be that I use known credentials in the backend and only log in with these.
My API is REST/JSON based, with relying party, user, challenge, pubKey etc...
My integration tests are Java based (spring boot starter test)
I am mainly interested in how to integration test the server without the client side. Are there utility programs or libraries that can handle authenticators and return the correct data/json objects?
I have looked at Testing WebAuthn via REST tool, however, I am not interested in testing the specification, since I am using a library, I only want to ensure that I applied the library correctly to my code.
A two-factor-authentication flow where the user is asked for their second factor—a WebAuthn credential—if they've registered one. A credential management interface: a list of credentials that enables users to rename and delete credentials.
User login flows supported Single factor: Username + FIDO2 credential. Second factor: Username + password + FIDO2 credential. Passwordless single factor: FIDO2 discoverable credential (a 'discoverable credential' stores user data on the authenticator)
In WebAuthn, a server must provide data that binds a user to a credential (a private-public keypair); this data includes identifiers for the user and organization (also known as the "relying party"). The website would then use the Web Authentication API to prompt the user to create a new keypair.
If you are only interested in testing the server side, you can write a simple webpage with buttons that exercise your endpoints and call navigator.credentials.(create|get)
. You can then instrument a browser using Selenium 4+, set up Virtual Authenticators, and run tests against that webpage. Take a look at the selenium tests for an example. The code to set up the authenticators looks like this in java:
VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
options.setTransport(Transport.INTERNAL)
.hasUserVerification(true)
.isUserVerified(true);
VirtualAuthenticator authenticator =
((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);
Pay attention to setting up the authenticator with the right settings to match your webauthn call. You should pick the right user verification support, resident keys support, and internal (i.e. platform) vs usb / nfc / ble (i.e. cross-platform) transport.
If you're using an older version of selenium, you'll have to manually define the commands yourself. The code should look like
browser.driver.getExecutor().defineCommand(
"AddVirtualAuthenticator", "POST", "/session/:sessionId/webauthn/authenticator");
// ...
Command addVirtualAuthCommand = new Command("AddVirtualAuthenticator");
addVirtualAuthCommand.setParameter("protocol", "ctap2");
addVirtualAuthCommand.setParameter("transport", "usb");
browser.driver.getExecutor().execute(addVirtualAuthCommand);
Running selenium tests might take a bit of work if you aren't already using it for integration testing. However, this implementation will very closely match reality. From the browser's perspective, the virtual authenticator is real hardware. The response from the authenticator will be processed by the browser as if it was real.
At the moment, only chromium based browsers support Virtual Authenticators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With