Fix bug PublicKeyCredentialUserEntityRepository saves anonymousUser

Issue gh-16385

Signed-off-by: Borghi <137845283+Borghii@users.noreply.github.com>
This commit is contained in:
Borghi 2025-02-16 22:50:34 -03:00
parent 946812691e
commit 0bc9313fdd
2 changed files with 25 additions and 3 deletions

View File

@ -46,6 +46,7 @@ import com.webauthn4j.data.client.challenge.DefaultChallenge;
import com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput; import com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput;
import com.webauthn4j.server.ServerProperty; import com.webauthn4j.server.ServerProperty;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl; import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -333,9 +334,7 @@ public class Webauthn4JRelyingPartyOperations implements WebAuthnRelyingPartyOpe
public PublicKeyCredentialRequestOptions createCredentialRequestOptions( public PublicKeyCredentialRequestOptions createCredentialRequestOptions(
PublicKeyCredentialRequestOptionsRequest request) { PublicKeyCredentialRequestOptionsRequest request) {
Authentication authentication = request.getAuthentication(); Authentication authentication = request.getAuthentication();
// FIXME: do not load credentialRecords if anonymous List<CredentialRecord> credentialRecords = findCredentialRecords(authentication);
PublicKeyCredentialUserEntity userEntity = findUserEntityOrCreateAndSave(authentication.getName());
List<CredentialRecord> credentialRecords = this.userCredentials.findByUserId(userEntity.getId());
return PublicKeyCredentialRequestOptions.builder() return PublicKeyCredentialRequestOptions.builder()
.allowCredentials(credentialDescriptors(credentialRecords)) .allowCredentials(credentialDescriptors(credentialRecords))
.challenge(Bytes.random()) .challenge(Bytes.random())
@ -346,6 +345,17 @@ public class Webauthn4JRelyingPartyOperations implements WebAuthnRelyingPartyOpe
.build(); .build();
} }
private List<CredentialRecord> findCredentialRecords(Authentication authentication) {
if (authentication instanceof AnonymousAuthenticationToken) {
return Collections.emptyList();
}
PublicKeyCredentialUserEntity userEntity = this.userEntities.findByUsername(authentication.getName());
if (userEntity == null) {
return Collections.emptyList();
}
return this.userCredentials.findByUserId(userEntity.getId());
}
@Override @Override
public PublicKeyCredentialUserEntity authenticate(RelyingPartyAuthenticationRequest request) { public PublicKeyCredentialUserEntity authenticate(RelyingPartyAuthenticationRequest request) {
PublicKeyCredentialRequestOptions requestOptions = request.getRequestOptions(); PublicKeyCredentialRequestOptions requestOptions = request.getRequestOptions();

View File

@ -536,6 +536,18 @@ class Webauthn4jRelyingPartyOperationsTests {
.isEqualTo(creationOptions.getAuthenticatorSelection().getUserVerification()); .isEqualTo(creationOptions.getAuthenticatorSelection().getUserVerification());
} }
@Test
void shouldReturnEmptyCredentialsWhenUserIsAnonymous() {
AnonymousAuthenticationToken authentication = new AnonymousAuthenticationToken("key", "anonymousUser",
Set.of(() -> "ROLE_ANONYMOUS"));
PublicKeyCredentialRequestOptionsRequest createRequest = new ImmutablePublicKeyCredentialRequestOptionsRequest(
authentication);
PublicKeyCredentialRequestOptions credentialRequestOptions = this.rpOperations
.createCredentialRequestOptions(createRequest);
assertThat(credentialRequestOptions.getAllowCredentials()).isEmpty();
}
private static AuthenticatorAttestationResponse setFlag(byte... flags) throws Exception { private static AuthenticatorAttestationResponse setFlag(byte... flags) throws Exception {
AuthenticatorAttestationResponseBuilder authAttResponseBldr = TestAuthenticatorAttestationResponse AuthenticatorAttestationResponseBuilder authAttResponseBldr = TestAuthenticatorAttestationResponse
.createAuthenticatorAttestationResponse(); .createAuthenticatorAttestationResponse();