Reputation: 131
In my use case, there is a registration page that triggers the browser-specific webauthn flow. For example in Chrome on a Mac you will see this series of popups:
Besides https://w3c.github.io/webauthn/#add-virtual-authenticator I haven't found much documentation about authenticating with webauthn as part of a selenium test. What resources are available to help devs figure out how to test webauthn with Selenium in JavaScript? I have also checked out https://github.com/SeleniumHQ/selenium/issues/7829 but the example test case does not make sense to me. Examples would be hugely appreciated.
Update with solution for js:
import { Command } from 'selenium-webdriver/lib/command';
addVirtualAuthenticator = async () => {
await this.driver.getSession().then(async session => {
this.driver
.getExecutor()
.defineCommand('AddVirtualAuthenticator', 'POST', `/session/${session.id_}/webauthn/authenticator`);
let addVirtualAuthCommand = new Command('AddVirtualAuthenticator');
addVirtualAuthCommand.setParameter('protocol', 'ctap2');
addVirtualAuthCommand.setParameter('transport', 'internal');
addVirtualAuthCommand.setParameter('hasResidentKey', true);
addVirtualAuthCommand.setParameter('isUserConsenting', true);
await this.driver.getExecutor().execute(addVirtualAuthCommand);
});
};
Note that this.driver
is of type WebDriver
.
Call addVirtualAuthenticator
before hitting any code that interacts with navigator
(in our case user registration involved a call to navigator.credentials.create
). If you need access to the publicKey, i.e. via navigator.credentials.get({ publicKey: options })
during login, then hasResidentKey
is critical.
Upvotes: 3
Views: 5668
Reputation: 978
This is worst practice in selenium
Two Factor Authentication shortly know as 2FA is a authorization mechanism where One Time Password(OTP) is generated using “Authenticator” mobile apps such as “Google Authenticator”, “Microsoft Authenticator” etc., or by SMS, e-mail to authenticate. Automating this seamlessly and consistently is a big challenge in Selenium. There are some ways to automate this process. But that will be another layer on top of our Selenium tests and not secured as well. So, you can avoid automating 2FA.
There are few options to get around 2FA checks:
1.Disable 2FA for certain Users in the test environment, so that you can use those user credentials in the automation. 2.Disable 2FA in your test environment. 3.Disable 2FA if you login from certain IPs. That way we can configure our test machine IPs to avoid this.
Upvotes: -2
Reputation: 601
A good resource for an example if you're implementing this in java and using selenium 4 is the tests on selenium itself. You basically need to
Create a virtual authenticator
In your case, you should set the transport to internal
and hasUserVerification to true
to simulate touchID.
VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
options.setTransport(Transport.INTERNAL)
.hasUserVerification(true)
.isUserVerified(true);
VirtualAuthenticator authenticator =
((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);
Perform the action that triggers registration.
If everything goes right, the browser should not show a dialog. Instead, it should immediately return a credential.
For any other language or selenium version, you will need to drop into calling the WebDriver protocol directly. As you pointed out, the W3C spec has documentation on the protocol endpoints.
For java, it might be something 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);
For javascript, you should be able to use defineCommand and webDriver.execute in a similar fashion.
Upvotes: 5