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-minimal
withwebauthn-server-core
. -
If using JDK 14 or earlier, add a JCA provider for the
EdDSA
algorithms. -
Remove uses of removed features.
-
Update uses of renamed and replaced features.
-
Replace any implementations of
MetadataService
withAttestationTrustSource
. -
Rename imports of classes in
com.yubico.fido.metadata
. -
Update
getUserVerification()
andgetResidentKey()
calls to expectOptional
values.
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
icon
field inRelyingPartyIdentity
andUserIdentity
, 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("[email protected]") .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.webauthn
package 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
Attestation
andTransport
, 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-attestation
module, which provides the typeMetadataBlobPayloadEntry
as a replacement forAttestation
and reusesAuthenticatorTransport
as a replacement forTransport
.
-
Methods
requireResidentKey(boolean)
andisRequireResidentKey()
inAuthenticatorSelectionCriteria
have 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:
-
MetadataService
implementations were expected to validate the attestation certificate path.AttestationTrustSource
implementations are not; instead they only need to retrieve the trust root certificates. TheRelyingParty.finishRegistration
method will perform certificate path validation internally and report the result viaRegistrationResult.isAttestationTrusted()
. TheAttestationTrustSource
may also return aCertStore
of untrusted certificates and CRLs that may be needed for certificate path validation, and/or disable certificate revocation checking for a particular query. -
MetadataService
implementations return attestation metadata.AttestationTrustSource
only returns what’s necessary for the certificate path validation. Implementations may provide additional methods for accessing attestation metadata, butRelyingParty
will 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...
}