The 2.0 release of the webauthn-server-core module
removes some deprecated features
and completely replaces the optional subsystem for attestation metadata.
This guide aims to help migrating between versions.
If you find this migration guide to be incomplete, incorrect, or otherwise difficult to follow, please let us know!
This is the migration guide for the core library.
The webauthn-server-attestation module has
its own migration guide.
Here is a high-level outline of what needs to be updated:
-
Replace dependency on
webauthn-server-core-minimalwithwebauthn-server-core. -
If using JDK 14 or earlier, add a JCA provider for the
EdDSAalgorithms. -
Remove uses of removed features.
-
Update uses of renamed and replaced features.
-
Replace any implementations of
MetadataServicewithAttestationTrustSource. -
Rename imports of classes in
com.yubico.fido.metadata. -
Update
getUserVerification()andgetResidentKey()calls to expectOptionalvalues.
Although the next section references version 2.4.0-RC2 for reasons detailed there,
this migration guide is written for version 2.0.0 of the
webauthn-server-core module. Later 2.x versions may introduce new features
but should remain compatible without further changes; please consult the
release notes
for an up to date list of new features.
If you were depending on the webauthn-server-core-minimal module,
update the dependency to webauthn-server-core instead.
Maven example:
<dependency>
<groupId>com.yubico</groupId>
- <artifactId>webauthn-server-core-minimal</artifactId>
- <version>1.12.2</version>
+ <artifactId>webauthn-server-core</artifactId>
+ <version>2.4.0-RC2</version>
<scope>compile</scope>
</dependency>Gradle:
-compile 'com.yubico:webauthn-server-core-minimal:1.12.2'
+compile 'com.yubico:webauthn-server-core:2.4.0-RC2'|
Warning
|
Backwards-incompatible regression in versions 2.0.0 to 2.4.0-RC1
Versions in the inclusive range |
The library no longer depends explicitly on BouncyCastle for cryptography back-ends. For applications running on JRE 15 or later this should not make a noticeable difference and no action should be needed. However, JRE 14 and earlier do not include EdDSA providers by default, so you need to add a JCA provider yourself. For example, you can use BouncyCastle. First, add the dependency.
Maven example:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
<scope>compile</scope>
</dependency>Gradle:
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'Then set up the provider. This should be done before instantiating
RelyingParty.
Example:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
Security.addProvider(new BouncyCastleProvider());Several fields, methods and settings have been removed:
-
The
iconfield inRelyingPartyIdentityandUserIdentity, and its associated methods. They were removed in WebAuthn Level 2 and have no replacement.Example:
RelyingPartyIdentity rpIdentity = RelyingPartyIdentity.builder() .id("example.org") .name("Example Service") - .icon(new URL("https://example.org/favicon.ico")) .build(); UserIdentity userIdentity = UserIdentity.builder() .name("test@example.org") .displayName("Test User") .id(new ByteArray(new byte[] { 1, 2, 3, 4 })) - .icon(new URL("https://example.org/user.png")) .build(); -
The setting
allowUnrequestedExtensions(boolean)inRelyingParty.WebAuthn Level 2 now recommends that unrequested extensions should be allowed, so this setting has been removed and is now always enabled.
Example:
RelyingParty rp = RelyingParty .builder() .identity(rpIdentity) .credentialRepository(credentialRepo) - .allowUnrequestedExtensions(true) .build() -
Enum value
AttestationType.ECDAA.This attestation type was removed from WebAuthn Level 2. ECDAA support has not been implemented in this library, so this value could in practice never be returned.
Example:
RelyingParty rp = /* ... */; RegistrationResult result = rp.finishRegistration(/* ... */); switch (result.getAttestationType()) { - case ECDAA: - // Do something... - break; - default: // Do something else... break; } -
Methods
RegistrationResult.getWarnings()andAssertionResult.getWarnings().These are now always empty. Any warnings are instead logged via SLF4J in the
com.yubico.webauthnpackage and its subpackages.Example:
RelyingParty rp = /* ... */; RegistrationResult result = rp.finishRegistration(/* ... */); -for (String warning : result.getWarnings()) { - // Do something... -} AssertionResult result = rp.finishAssertion(/* ... */); -for (String warning : result.getWarnings()) { - // Do something... -}
-
Types
AttestationandTransport, methodsRegistrationResult.getAttestationMetadata()andAuthenticatorTransport.fromU2fTransport()have been removed in an overhaul of the framework for attestation metadata. The core library no longer exposes attestation metadata directly in its result types, instead each metadata source may provide its own interfaces for retrieving and working with attestation metadata. See for example thewebauthn-server-attestationmodule, which provides the typeMetadataBlobPayloadEntryas a replacement forAttestationand reusesAuthenticatorTransportas a replacement forTransport.
-
Methods
requireResidentKey(boolean)andisRequireResidentKey()inAuthenticatorSelectionCriteriahave been replaced byresidentKey(ResidentKeyRequirement)andgetResidentKey(), respectively.Replace
requireResidentKey(false)withresidentKey(ResidentKeyRequirement.DISCOURAGED). Example:RelyingParty rp = /* ... */; PublicKeyCredentialCreationOptions pkcco = rp.startRegistration( StartRegistrationOptions .builder() .user(userId) .authenticatorSelection( AuthenticatorSelectionCriteria .builder() - .requireResidentKey(false) + .residentKey(ResidentKeyRequirement.DISCOURAGED) .build() ) .build() );Replace
requireResidentKey(true)withresidentKey(ResidentKeyRequirement.REQUIRED). Example:RelyingParty rp = /* ... */; PublicKeyCredentialCreationOptions pkcco = rp.startRegistration( StartRegistrationOptions .builder() .user(userId) .authenticatorSelection( AuthenticatorSelectionCriteria .builder() - .requireResidentKey(true) + .residentKey(ResidentKeyRequirement.REQUIRED) .build() ) .build() );
The MetadataService interface has been replaced with
AttestationTrustSource.
The new interface has some key differences:
-
MetadataServiceimplementations were expected to validate the attestation certificate path.AttestationTrustSourceimplementations are not; instead they only need to retrieve the trust root certificates. TheRelyingParty.finishRegistrationmethod will perform certificate path validation internally and report the result viaRegistrationResult.isAttestationTrusted(). TheAttestationTrustSourcemay also return aCertStoreof untrusted certificates and CRLs that may be needed for certificate path validation, and/or disable certificate revocation checking for a particular query. -
MetadataServiceimplementations return attestation metadata.AttestationTrustSourceonly returns what’s necessary for the certificate path validation. Implementations may provide additional methods for accessing attestation metadata, butRelyingPartywill not integrate them in the core result types.
See the
JavaDoc
for AttestationTrustSource for details on how to implement it,
and see the
FidoMetadataService
class in the
webauthn-server-attestation module
for a reference implementation.
The com.yubico.fido.metadata package appears in both
the webauthn-server-core and webauthn-server-attestation modules.
This causes split package name clash in JPMS (Java Platform Module System),
so the classes in the core module have been moved
to the com.yubico.webauthn.extension.uvm package to avoid this name conflict.
Update any imports of these classes.
Example:
-import com.yubico.fido.metadata.KeyProtectionType;
-import com.yubico.fido.metadata.MatcherProtectionType;
-import com.yubico.fido.metadata.UserVerificationMethod;
+import com.yubico.webauthn.extension.uvm.KeyProtectionType;
+import com.yubico.webauthn.extension.uvm.MatcherProtectionType;
+import com.yubico.webauthn.extension.uvm.UserVerificationMethod;The default "preferred" for userVerification has
turned out to cause confusion.
Therefore, browsers have started issuing console warnings
when userVerification is not set explicitly.
This library has mirrored the defaults for
PublicKeyCredentialRequestOptions.userVerification
and
AuthenticatorSelectionCriteria.userVerification,
but this inadvertently suppresses any browser console warnings
since the library emits parameter objects with an explicit value set,
even if the value was not explicitly set at the library level.
The defaults have therefore been removed,
and the corresponding getters now return Optional values.
For consistency, the same change applies to
AuthenticatorSelectionCriteria.residentKey
as well.
The setters for these settings remain unchanged,
but if you use the getters you need to expect Optional values instead.
Example:
PublicKeyCredentialCreationOptions pkcco = /* ... */;
if (pkcco
.getAuthenticatorSelectionCriteria()
- .map(AuthenticatorSelectionCriteria::getUserVerification)
+ .flatMap(AuthenticatorSelectionCriteria::getUserVerification)
.equals(Optional.of(UserVerificationRequirement.REQUIRED))) {
// Do something...
}
if (pkcco
.getAuthenticatorSelectionCriteria()
- .map(AuthenticatorSelectionCriteria::getResidentKey)
+ .flatMap(AuthenticatorSelectionCriteria::getResidentKey)
.equals(Optional.of(ResidentKeyRequirement.REQUIRED))) {
// Do something...
}
PublicKeyCredentialRequestOptions pkcro = /* ... */;
if (pkcro
.getUserVerification()
- == UserVerificationRequirement.REQUIRED)) {
+ .equals(Optional.of(UserVerificationRequirement.REQUIRED))) {
// Do something...
}