The 2.0
release of the webauthn-server-attestation
module
makes lots of breaking changes compared to the 1.x
versions.
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!
Here is a high-level outline of what needs to be updated:
-
Replace uses of
StandardMetadataService
and its related classes withFidoMetadataService
andFidoMetadataDownloader
. -
Update the name of the
RelyingParty
integration point frommetadataService
toattestationTrustSource
. -
RegistrationResult
no longer includes attestation metadata, instead you’ll need to retrieve it separately after a successful registration. -
Replace uses of the
Attestation
result type withMetadataBLOBPayloadEntry
.
This migration guide is written for version 2.1.0
of the
webauthn-server-attestation
module. Later 2.x
versions may introduce new
features but should remain compatible without further changes; consult the
release notes for a full list of new features.
StandardMetadataService
and its constituent classes have been removed
in favour of
FidoMetadataService
and
FidoMetadataDownloader
.
See the Getting started documentation
for details on how to configure and construct them.
Example 1.x
code:
MetadataService metadataService =
new StandardMetadataService(
StandardMetadataService.createDefaultAttestationResolver(
StandardMetadataService.createDefaultTrustResolver()
));
Example 2.0
code:
FidoMetadataService metadataService = FidoMetadataService.builder()
.useBlob(FidoMetadataDownloader.builder()
.expectLegalHeader("Retrieval and use of this BLOB indicates acceptance of the appropriate agreement located at https://fidoalliance.org/metadata/metadata-legal-terms/")
.useDefaultTrustRoot()
.useTrustRootCacheFile(new File("fido-mds-trust-root-cache.bin"))
.useDefaultBlob()
.useBlobCacheFile(new File("fido-mds-blob-cache.bin"))
.build()
.loadCachedBlob()
)
.build();
You may also need to add external logic to occasionally re-run
loadCachedBlob()
and/or
refreshBlob()
and reconstruct the FidoMetadataService
,
as FidoMetadataService
will not automatically update the BLOB on its own.
FidoMetadataService
integrates with
RelyingParty
in much the same way as StandardMetadataService
,
although the name of the setting has changed.
Example 1.x
code:
RelyingParty rp = RelyingParty.builder()
.identity(rpIdentity)
.credentialRepository(credentialRepo)
.attestationConveyancePreference(AttestationConveyancePreference.DIRECT)
- .metadataService(metadataService))
.allowUntrustedAttestation(true)
.build();
Example 2.0
code:
RelyingParty rp = RelyingParty.builder()
.identity(rpIdentity)
.credentialRepository(credentialRepo)
.attestationConveyancePreference(AttestationConveyancePreference.DIRECT)
+ .attestationTrustSource(metadataService)
.allowUntrustedAttestation(true)
.build();
In 1.x
,
RegistrationResult
could include an Attestation
object with attestation metadata,
if a metadata service was configured and the authenticator matched anything in the metadata service.
In order to keep
RelyingParty
and the new
AttestationTrustSource
interface decoupled from any particular format of attestation metadata, this result field has been removed.
Instead, use the findEntries
methods of
FidoMetadataService
to retrieve attestation metadata after a successful registration, if needed.
Example 1.x
code:
RegistrationResult result = rp.finishRegistration(/* ... */);
Optional<String> authenticatorName = result.getAttestationMetadata()
.flatMap(Attestation::getDeviceProperties)
.map(deviceProps -> deviceProps.get("description"));
Example 2.0
code:
FidoMetadataService mds = /* ... */;
RegistrationResult result = rp.finishRegistration(/* ... */);
Optional<String> authenticatorName = mds.findEntries(result)
.stream()
.findAny()
.flatMap(MetadataBLOBPayloadEntry::getMetadataStatement)
.flatMap(MetadataStatement::getDescription);
This ties in with the previous step, and much of it will likely be done already.
However if your front-end accesses and/or displays contents of an Attestation
object,
it will need to be updated to work with
MetadataBLOBPayloadEntry
or similar types instead.
Example 1.x
code:
var registrationResult = fetch(/* ... */).then(response => response.json());
-var authenticatorName = registrationResult.attestationMetadata?.deviceProperties?.description;
Example 2.0
code:
var registrationResult = fetch(/* ... */).then(response => response.json());
+var authenticatorName = registrationResult.attestationMetadata?.metadataStatement?.description;