Skip to content

Commit 9c3b119

Browse files
committed
webauthn registerCredential returns transports
The webauthn support previously did not pass the transports to webauthn4j. This meant that the result of Webauthn4jRelyingPartyOperations.registerCredential did not have any transports either. This commit ensures that the transports are passed to the webauth4j lib and then returned in the result of registerCredential. Closes gh-16084
1 parent cc2506b commit 9c3b119

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

web/src/main/java/org/springframework/security/web/webauthn/management/Webauthn4JRelyingPartyOperations.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.time.Instant;
2121
import java.util.ArrayList;
2222
import java.util.Collections;
23+
import java.util.HashSet;
2324
import java.util.List;
2425
import java.util.Set;
2526
import java.util.function.Consumer;
@@ -254,7 +255,9 @@ public CredentialRecord registerCredential(RelyingPartyRegistrationRequest rpReg
254255
boolean userPresenceRequired = true;
255256
List<com.webauthn4j.data.PublicKeyCredentialParameters> pubKeyCredParams = convertCredentialParamsToWebauthn4j(
256257
creationOptions.getPubKeyCredParams());
257-
RegistrationRequest webauthn4jRegistrationRequest = new RegistrationRequest(attestationObject, clientDataJSON);
258+
Set<String> transports = convertTransportsToString(response);
259+
RegistrationRequest webauthn4jRegistrationRequest = new RegistrationRequest(attestationObject, clientDataJSON,
260+
transports);
258261
RegistrationParameters registrationParameters = new RegistrationParameters(serverProperty, pubKeyCredParams,
259262
userVerificationRequired, userPresenceRequired);
260263
RegistrationData registrationData = this.webAuthnManager.validate(webauthn4jRegistrationRequest,
@@ -283,6 +286,17 @@ public CredentialRecord registerCredential(RelyingPartyRegistrationRequest rpReg
283286
return userCredential;
284287
}
285288

289+
private static Set<String> convertTransportsToString(AuthenticatorAttestationResponse response) {
290+
if (response.getTransports() == null) {
291+
return null;
292+
}
293+
Set<String> transports = new HashSet<>(response.getTransports().size());
294+
for (AuthenticatorTransport transport : response.getTransports()) {
295+
transports.add(transport.getValue());
296+
}
297+
return transports;
298+
}
299+
286300
private List<com.webauthn4j.data.PublicKeyCredentialParameters> convertCredentialParamsToWebauthn4j(
287301
List<PublicKeyCredentialParameters> parameters) {
288302
return parameters.stream().map(this::convertParamToWebauthn4j).collect(Collectors.toUnmodifiableList());

web/src/test/java/org/springframework/security/web/webauthn/management/Webauthn4jRelyingPartyOperationsTests.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.springframework.security.web.webauthn.api.AuthenticatorAttestationResponse;
4646
import org.springframework.security.web.webauthn.api.AuthenticatorAttestationResponse.AuthenticatorAttestationResponseBuilder;
4747
import org.springframework.security.web.webauthn.api.AuthenticatorSelectionCriteria;
48+
import org.springframework.security.web.webauthn.api.AuthenticatorTransport;
4849
import org.springframework.security.web.webauthn.api.Bytes;
4950
import org.springframework.security.web.webauthn.api.CredentialRecord;
5051
import org.springframework.security.web.webauthn.api.PublicKeyCredential;
@@ -224,6 +225,47 @@ void registerCredentialWhenRpRegistrationRequestNullThenIllegalArgumentException
224225
assertThatIllegalArgumentException().isThrownBy(() -> this.rpOperations.registerCredential(null));
225226
}
226227

228+
@Test
229+
void registerCredentialWhenDefaultTransportsThenSuccess() {
230+
PublicKeyCredentialCreationOptions creationOptions = TestPublicKeyCredentialCreationOptions
231+
.createPublicKeyCredentialCreationOptions()
232+
.build();
233+
PublicKeyCredential<AuthenticatorAttestationResponse> publicKeyCredential = TestPublicKeyCredential
234+
.createPublicKeyCredential()
235+
.build();
236+
RelyingPartyPublicKey rpPublicKey = new RelyingPartyPublicKey(publicKeyCredential, this.label);
237+
238+
ImmutableRelyingPartyRegistrationRequest rpRegistrationRequest = new ImmutableRelyingPartyRegistrationRequest(
239+
creationOptions, rpPublicKey);
240+
CredentialRecord credentialRecord = this.rpOperations.registerCredential(rpRegistrationRequest);
241+
assertThat(credentialRecord).isNotNull();
242+
assertThat(credentialRecord.getCredentialId()).isNotNull();
243+
assertThat(credentialRecord.getTransports()).containsExactlyInAnyOrder(AuthenticatorTransport.INTERNAL,
244+
AuthenticatorTransport.HYBRID);
245+
}
246+
247+
@Test
248+
void registerCredentialWhenInternalTransportThenCredentialRecordHasTransport() {
249+
PublicKeyCredentialCreationOptions creationOptions = TestPublicKeyCredentialCreationOptions
250+
.createPublicKeyCredentialCreationOptions()
251+
.build();
252+
AuthenticatorAttestationResponse response = TestAuthenticatorAttestationResponse
253+
.createAuthenticatorAttestationResponse()
254+
.transports(AuthenticatorTransport.INTERNAL)
255+
.build();
256+
PublicKeyCredential<AuthenticatorAttestationResponse> publicKeyCredential = TestPublicKeyCredential
257+
.createPublicKeyCredential()
258+
.response(response)
259+
.build();
260+
RelyingPartyPublicKey rpPublicKey = new RelyingPartyPublicKey(publicKeyCredential, this.label);
261+
262+
ImmutableRelyingPartyRegistrationRequest rpRegistrationRequest = new ImmutableRelyingPartyRegistrationRequest(
263+
creationOptions, rpPublicKey);
264+
CredentialRecord credentialRecord = this.rpOperations.registerCredential(rpRegistrationRequest);
265+
assertThat(credentialRecord).isNotNull();
266+
assertThat(credentialRecord.getTransports()).containsExactlyInAnyOrder(AuthenticatorTransport.INTERNAL);
267+
}
268+
227269
@Test
228270
void registerCredentialWhenExistsThenException() {
229271
PublicKeyCredentialCreationOptions creationOptions = TestPublicKeyCredentialCreationOptions

0 commit comments

Comments
 (0)