<?php namespace App\WebAuthn; use App\WebAuthn\Repository\PublicKeyCredentialSourceRepositoryImpl; use Cose\Algorithm\Manager; use Cose\Algorithm\Signature\ECDSA\ES256; use Cose\Algorithm\Signature\RSA\RS256; use Cose\Algorithms; use Webauthn\AttestationStatement\AttestationObjectLoader; use Webauthn\AttestationStatement\AttestationStatementSupportManager; use Webauthn\AttestationStatement\NoneAttestationStatementSupport; use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler; use Webauthn\AuthenticatorAssertionResponseValidator; use Webauthn\AuthenticatorAttestationResponseValidator; use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialParameters; use Webauthn\PublicKeyCredentialRpEntity; use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; use Webauthn\TokenBinding\IgnoreTokenBindingHandler; class WebAuthnService { private static $rpName = "开心鄢的录播查询小站"; private static $rpId = "comment.sc.jerryyan.top"; private static $timeout = 45000; private static $publicKeyCredentialSourceRepositoryInstance = null; private static $authenticatorAssertionResponseValidator = null; private static $attestationStatementSupportManager = null; public static function createRequestOptions(PublicKeyCredentialUserEntity $userEntity, string $challenge): PublicKeyCredentialCreationOptions { $publicKeyCredentialParametersList = [ new PublicKeyCredentialParameters("public-key", Algorithms::COSE_ALGORITHM_ES256), new PublicKeyCredentialParameters("public-key", Algorithms::COSE_ALGORITHM_RS256), ]; return new PublicKeyCredentialCreationOptions( static::getRpEntity(), $userEntity, $challenge, $publicKeyCredentialParametersList, static::$timeout ); } public static function getPublicKeyCredentialSourceRepository(): PublicKeyCredentialSourceRepository { if (static::$publicKeyCredentialSourceRepositoryInstance === null) { static::$publicKeyCredentialSourceRepositoryInstance = new PublicKeyCredentialSourceRepositoryImpl(); } return static::$publicKeyCredentialSourceRepositoryInstance; } public static function getAuthenticatorAssertionResponseValidator(): AuthenticatorAssertionResponseValidator { if (static::$authenticatorAssertionResponseValidator === null) { $algorithmManager = new Manager(); $algorithmManager->add(new ES256()); $algorithmManager->add(new RS256()); static::$authenticatorAssertionResponseValidator = new AuthenticatorAssertionResponseValidator( static::getPublicKeyCredentialSourceRepository(), new IgnoreTokenBindingHandler(), new ExtensionOutputCheckerHandler(), $algorithmManager ); } return static::$authenticatorAssertionResponseValidator; } public static function getAuthenticatorAttestationResponseValidator(): AuthenticatorAttestationResponseValidator { return new AuthenticatorAttestationResponseValidator( static::getAttestationStatementSupportManager(), static::getPublicKeyCredentialSourceRepository(), new IgnoreTokenBindingHandler(), new ExtensionOutputCheckerHandler() ); } public static function getPublicKeyCredentialLoader(): PublicKeyCredentialLoader { return new PublicKeyCredentialLoader( static::getAttestationObjectLoader() ); } public static function getAttestationObjectLoader(): AttestationObjectLoader { return new AttestationObjectLoader(static::getAttestationStatementSupportManager()); } private static function getAttestationStatementSupportManager(): AttestationStatementSupportManager { if (static::$attestationStatementSupportManager === null) { static::$attestationStatementSupportManager = new AttestationStatementSupportManager(); static::$attestationStatementSupportManager->add(new NoneAttestationStatementSupport()); } return static::$attestationStatementSupportManager; } private static function getRpEntity(): PublicKeyCredentialRpEntity { return new PublicKeyCredentialRpEntity( static::$rpName, static::$rpId ); } }