From 61579d39aaa502262e86a9ceb6fd3e3bbd58ec01 Mon Sep 17 00:00:00 2001 From: zll600 <3400692417@qq.com> Date: Fri, 28 Nov 2025 09:46:50 +0800 Subject: [PATCH 1/3] feat: add requireResidentKey property for backward compatibility with WebAuthn Level 3 spec --- .../src/AuthenticatorSelectionCriteria.php | 15 +++++++++++++++ .../Unit/AuthenticatorSelectionCriteriaTest.php | 3 ++- .../functional/Firewall/RegistrationAreaTest.php | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/webauthn/src/AuthenticatorSelectionCriteria.php b/src/webauthn/src/AuthenticatorSelectionCriteria.php index 8ef98cde9..160cbdd35 100644 --- a/src/webauthn/src/AuthenticatorSelectionCriteria.php +++ b/src/webauthn/src/AuthenticatorSelectionCriteria.php @@ -48,6 +48,15 @@ class AuthenticatorSelectionCriteria self::RESIDENT_KEY_REQUIREMENT_DISCOURAGED, ]; + /** + * Legacy property for backward compatibility. + * + * requireResidentKey is based on residentKey for backward compatibility + * Per WebAuthn Level 3 spec: "Relying Parties SHOULD set it to true if, and only if, residentKey is set to required." + * Only set when residentKey is "required"; leave uninitialized otherwise + */ + public readonly ?bool $requireResidentKey; + public function __construct( public null|string $authenticatorAttachment = null, public string $userVerification = self::USER_VERIFICATION_REQUIREMENT_PREFERRED, @@ -62,6 +71,12 @@ public function __construct( in_array($residentKey, self::RESIDENT_KEY_REQUIREMENTS, true) || throw new InvalidArgumentException( 'Invalid resident key' ); + + if ($residentKey === self::RESIDENT_KEY_REQUIREMENT_REQUIRED) { + $this->requireResidentKey = true; + } else { + $this->requireResidentKey = null; + } } public static function create( diff --git a/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php b/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php index 7292bb26f..3462b81cb 100644 --- a/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php +++ b/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php @@ -57,7 +57,7 @@ public function anAuthenticatorSelectionCriteriaCanBeCreatedAndValueAccessed(): public function anAuthenticatorSelectionCriteriaWithResidentKeyCanBeCreatedAndValueAccessed(): void { // Given - $expectedJson = '{"userVerification":"required","residentKey":"required","authenticatorAttachment":"platform"}'; + $expectedJson = '{"requireResidentKey":true,"userVerification":"required","residentKey":"required","authenticatorAttachment":"platform"}'; $authenticatorSelectionCriteria = AuthenticatorSelectionCriteria::create( AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM, AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED, @@ -80,6 +80,7 @@ public function anAuthenticatorSelectionCriteriaWithResidentKeyCanBeCreatedAndVa $data->authenticatorAttachment ); static::assertSame(AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_REQUIRED, $data->residentKey); + static::assertTrue($data->requireResidentKey); static::assertJsonStringEqualsJsonString($expectedJson, $this->getSerializer()->serialize($data, 'json', [ AbstractObjectNormalizer::SKIP_NULL_VALUES => true, ])); diff --git a/tests/symfony/functional/Firewall/RegistrationAreaTest.php b/tests/symfony/functional/Firewall/RegistrationAreaTest.php index 0196d26a7..cd839eea3 100644 --- a/tests/symfony/functional/Firewall/RegistrationAreaTest.php +++ b/tests/symfony/functional/Firewall/RegistrationAreaTest.php @@ -101,6 +101,7 @@ public function aValidRequestProcessed(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ + 'requireResidentKey' => true, 'authenticatorAttachment' => 'cross-platform', 'userVerification' => 'required', 'residentKey' => 'required', @@ -137,6 +138,7 @@ public function aValidRequestProcessedOnOtherHost(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ + 'requireResidentKey' => true, 'userVerification' => 'preferred', 'residentKey' => 'required', ], $data['authenticatorSelection']); @@ -181,6 +183,7 @@ public function aValidRequestProcessedWithExtensions(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ + 'requireResidentKey' => true, 'authenticatorAttachment' => 'platform', 'userVerification' => 'required', 'residentKey' => 'required', From d260f809f379ee73496773cd3bcda3e9dbc9711e Mon Sep 17 00:00:00 2001 From: zll600 <3400692417@qq.com> Date: Fri, 28 Nov 2025 09:58:36 +0800 Subject: [PATCH 2/3] Enable autowiring for ObjectNormalizer in Symfony test configuration --- tests/symfony/config/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/symfony/config/config.yml b/tests/symfony/config/config.yml index 48b8f2523..d6115f5ae 100644 --- a/tests/symfony/config/config.yml +++ b/tests/symfony/config/config.yml @@ -37,6 +37,7 @@ services: Symfony\Component\Serializer\Normalizer\ObjectNormalizer: tags: [ serializer.normalizer ] + autowire: true Webauthn\Tests\Bundle\Functional\MockClientCallback: ~ From dacede2bbbee2282bd25cf252d0bd31952194b79 Mon Sep 17 00:00:00 2001 From: zll600 <3400692417@qq.com> Date: Fri, 28 Nov 2025 12:57:26 +0800 Subject: [PATCH 3/3] feat: add new authenticator transport constants and deprecate AUTHENTICATOR_TRANSPORT_CABLE --- phpstan-baseline.neon | 9 +++++++++ src/webauthn/src/PublicKeyCredentialDescriptor.php | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 40979949e..43f86d176 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2321,3 +2321,12 @@ parameters: identifier: return.type count: 1 path: src/webauthn/src/SimpleFakeCredentialGenerator.php + + - + rawMessage: ''' + Fetching deprecated class constant AUTHENTICATOR_TRANSPORT_CABLE of class Webauthn\PublicKeyCredentialDescriptor: + Please use AUTHENTICATOR_TRANSPORT_BLE instead. Will be removed in 6.0.0 + ''' + identifier: classConstant.deprecated + count: 1 + path: src/webauthn/src/PublicKeyCredentialDescriptor.php diff --git a/src/webauthn/src/PublicKeyCredentialDescriptor.php b/src/webauthn/src/PublicKeyCredentialDescriptor.php index 09fd620d3..2f7cfc27d 100644 --- a/src/webauthn/src/PublicKeyCredentialDescriptor.php +++ b/src/webauthn/src/PublicKeyCredentialDescriptor.php @@ -14,8 +14,15 @@ class PublicKeyCredentialDescriptor final public const AUTHENTICATOR_TRANSPORT_BLE = 'ble'; + /** + * @deprecated Please use AUTHENTICATOR_TRANSPORT_BLE instead. Will be removed in 6.0.0 + */ final public const AUTHENTICATOR_TRANSPORT_CABLE = 'cable'; + final public const AUTHENTICATOR_TRANSPORT_SMART_CARD = 'smart-card'; + + final public const AUTHENTICATOR_TRANSPORT_HYBRID = 'hybrid'; + final public const AUTHENTICATOR_TRANSPORT_INTERNAL = 'internal'; final public const AUTHENTICATOR_TRANSPORTS = [ @@ -23,6 +30,8 @@ class PublicKeyCredentialDescriptor self::AUTHENTICATOR_TRANSPORT_NFC, self::AUTHENTICATOR_TRANSPORT_BLE, self::AUTHENTICATOR_TRANSPORT_CABLE, + self::AUTHENTICATOR_TRANSPORT_SMART_CARD, + self::AUTHENTICATOR_TRANSPORT_HYBRID, self::AUTHENTICATOR_TRANSPORT_INTERNAL, ];