I want to implement WebAuthn using Java/Vaadin for the client side.
My goal is to reach that point that any users can register/enroll a WebAuthn in the context of 2FA.
The created token should be saved on a privacyIDEA server for later use. It also handles the authentification of the users.
What I have done so far:
- Creating the web application with Vaadin (Java framework)
- Implementing methods for the token management in Java (still unfinished)
- Using a JavaScript client plugin to faciliate authentification against privacyIDEA server using WebAuthn tokens
Code snippet from JavaScript client-side library:
window.registerWebAuthn = function (challenge, rpName, rpId, userId, userName, displayName) {
const publicKeyCredentialCreationOptions = {
challenge: new Uint8Array(challenge),
rp: {
name: "rpName",
id : "rpId"
},
user: {
id: new Uint8Array(userId),
name: "userName",
displayName: "displayName"
}
};
navigator
.credentials
.create({publicKey: publicKeyCredentialCreationOptions})
.then(function (newCredentialInfo) {
console.log(newCredentialInfo);
}).catch(function (err) {
console.error(err);
});
};
The JavaScript function registerWebAuthn
takes several parameters and utilizes the WebAuthn API to create a new public key credential. The then
block handles the successful creation of the credential, and it logs the newCredentialInfo
to the console.
It is expected to start the WebAuthn registration process by pressing the button Create token. To do this, I call the Js function registerWebAuthn()
inside Vaadins executeJs()
function.
Vaadin/Java code:
@JsModule("./src/pi-webauthn.js")
public class MFAPageView {
private Button buttonPrimary0 = new Button();
public MFAPageView() {
buttonPrimary0.setText("Create token");
layoutColumn2.add(buttonPrimary0);
buttonPrimary0.addClickListener(e -> {
UI.getCurrent().getPage().executeJs("registerWebAuthn()");
}
}
How do I access the WebAuthn credentials in newCredentialInfo
and send them to privacyIDEA server to perform user authentification?
Do you have any idea?
2
Answers
The toJSON method is not yet widely supported, I’m afraid. So you need to grab the fields from the object and serialise them yourself in most cases.
You can encode
newCredentialInfo
with something like this:Yeah, probably clean that up a bit, but to illustrate the point.
Then you can return
encodedCredential
fromregisterWebAuthn()
and handle it in athen()
of yourexecuteJS()
call. Something like:Again, you might really want to clean up this code.
HTH even though it’s not exactly production ready.