Explorar o código

Fix bug PublicKeyCredentialUserEntityRepository saves anonymousUser

Issue gh-16385

Signed-off-by: Borghi <137845283+Borghii@users.noreply.github.com>
Borghi hai 6 meses
pai
achega
0bc9313fdd

+ 13 - 3
web/src/main/java/org/springframework/security/web/webauthn/management/Webauthn4JRelyingPartyOperations.java

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

+ 12 - 0
web/src/test/java/org/springframework/security/web/webauthn/management/Webauthn4jRelyingPartyOperationsTests.java

@@ -536,6 +536,18 @@ class Webauthn4jRelyingPartyOperationsTests {
 			.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 {
 		AuthenticatorAttestationResponseBuilder authAttResponseBldr = TestAuthenticatorAttestationResponse
 			.createAuthenticatorAttestationResponse();