WebAuthn初步接好

This commit is contained in:
2022-08-08 02:07:27 +08:00
parent 50934228ef
commit 30b38e3f4b
16 changed files with 1329 additions and 5 deletions

View File

@ -0,0 +1,69 @@
<?php
namespace App\WebAuthn\Repository;
use App\Models\WebauthnCredential;
use Webauthn\PublicKeyCredentialSource;
use Webauthn\PublicKeyCredentialSourceRepository;
use Webauthn\PublicKeyCredentialUserEntity;
class PublicKeyCredentialSourceRepositoryImpl implements PublicKeyCredentialSourceRepository
{
public function findOneByCredentialId(string $publicKeyCredentialId): ?PublicKeyCredentialSource
{
$model = $this->findOneModelByCredentialId($publicKeyCredentialId);
if ($model) {
return $model->getPublicKeyCredentialSourceAttribute();
} else {
return null;
}
}
/**
* @inheritDoc
*/
public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity): array
{
if ($publicKeyCredentialUserEntity->getId() == 0) {
$modelList = $this->findAllModelByTypeFree();
} else {
$modelList = $this->findAllModelByUserId($publicKeyCredentialUserEntity->getId());
}
return array_map(function (WebauthnCredential $cred) {
return $cred->getPublicKeyCredentialSourceAttribute();
}, $modelList);
}
public function saveCredentialSource(PublicKeyCredentialSource $publicKeyCredentialSource): void
{
$model = $this->findOneModelByCredentialId($publicKeyCredentialSource->getPublicKeyCredentialId());
if ($model === null) {
$model = new WebauthnCredential();
$model->setPublicKeyCredentialSourceAttribute($publicKeyCredentialSource);
}
$model->counter += 1;
$model->last_used_at = now();
$model->save();
}
private function findOneModelByCredentialId(string $publicKeyCredentialId): ?WebauthnCredential
{
/**
* @var WebauthnCredential
*/
return WebauthnCredential::query()->where(function ($query) use ($publicKeyCredentialId) {
$query->where("credential_id", "=", base64_encode($publicKeyCredentialId));
})->first();
}
private function findAllModelByTypeFree(): array
{
return WebauthnCredential::query()->where("type_free", "=", "1")->get()->toArray();
}
private function findAllModelByUserId(string $userId): array
{
return WebauthnCredential::query()->where("user_id", "=", $userId)->get()->toArray();
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\WebAuthn;
use App\WebAuthn\Repository\PublicKeyCredentialSourceRepositoryImpl;
use Cose\Algorithms;
use Webauthn\AuthenticatorSelectionCriteria;
use Webauthn\PublicKeyCredentialCreationOptions;
use Webauthn\PublicKeyCredentialParameters;
use Webauthn\PublicKeyCredentialRpEntity;
use Webauthn\PublicKeyCredentialSourceRepository;
use Webauthn\PublicKeyCredentialUserEntity;
class WebAuthnService
{
private static $rpName = "开心鄢的录播查询小站";
private static $rpId = "localhost";
private static $timeout = 45000;
private static $publicKeyCredentialSourceRepositoryInstance = 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;
}
private static function getRpEntity(): PublicKeyCredentialRpEntity
{
return new PublicKeyCredentialRpEntity(
static::$rpName,
static::$rpId
);
}
}