Web Authn(2/3)
后端工作基本完成 *上一条git提交备注写错了 *应该是添加相关依赖以及对配置文件的微调
This commit is contained in:
parent
67923425f8
commit
e74492dbb7
@ -8,6 +8,6 @@ class SimpleWebAuthnBrowser extends AssetBundle
|
|||||||
{
|
{
|
||||||
public $sourcePath = '@npm/simplewebauthn--browser/dist/bundle';
|
public $sourcePath = '@npm/simplewebauthn--browser/dist/bundle';
|
||||||
public $js = [
|
public $js = [
|
||||||
'index.js',
|
'index.umd.min.js',
|
||||||
];
|
];
|
||||||
}
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use app\models\PublicKeyCredentialSource;
|
use app\models\PublicKeyCredentialSourceRepository;
|
||||||
use app\models\User;
|
use app\models\User;
|
||||||
use app\utils\FileSizeHelper;
|
use app\utils\FileSizeHelper;
|
||||||
use OTPHP\TOTP;
|
use OTPHP\TOTP;
|
||||||
@ -10,19 +10,32 @@ use Random\RandomException;
|
|||||||
use ReCaptcha\ReCaptcha;
|
use ReCaptcha\ReCaptcha;
|
||||||
use Symfony\Component\Serializer\Serializer;
|
use Symfony\Component\Serializer\Serializer;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
use Webauthn\AttestationStatement\AttestationObjectLoader;
|
||||||
use Webauthn\AttestationStatement\AttestationStatementSupportManager;
|
use Webauthn\AttestationStatement\AttestationStatementSupportManager;
|
||||||
use Webauthn\AttestationStatement\NoneAttestationStatementSupport;
|
use Webauthn\AttestationStatement\NoneAttestationStatementSupport;
|
||||||
use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler;
|
|
||||||
use Webauthn\AuthenticatorAssertionResponse;
|
use Webauthn\AuthenticatorAssertionResponse;
|
||||||
use Webauthn\AuthenticatorAssertionResponseValidator;
|
use Webauthn\AuthenticatorAssertionResponseValidator;
|
||||||
use Webauthn\AuthenticatorAttestationResponse;
|
use Webauthn\AuthenticatorAttestationResponse;
|
||||||
use Webauthn\AuthenticatorAttestationResponseValidator;
|
use Webauthn\AuthenticatorAttestationResponseValidator;
|
||||||
|
use Webauthn\CeremonyStep\CeremonyStepManager;
|
||||||
|
use Webauthn\CeremonyStep\CeremonyStepManagerFactory;
|
||||||
|
use Webauthn\Denormalizer\AttestationObjectDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\AttestationStatementDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\AuthenticatorAssertionResponseDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\AuthenticatorAttestationResponseDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\AuthenticatorDataDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\AuthenticatorResponseDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\CollectedClientDataDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\PublicKeyCredentialDenormalizer;
|
||||||
|
use Webauthn\Denormalizer\WebauthnSerializerFactory;
|
||||||
use Webauthn\Exception\AuthenticatorResponseVerificationException;
|
use Webauthn\Exception\AuthenticatorResponseVerificationException;
|
||||||
use Webauthn\PublicKeyCredential;
|
use Webauthn\PublicKeyCredential;
|
||||||
use Webauthn\PublicKeyCredentialCreationOptions;
|
use Webauthn\PublicKeyCredentialCreationOptions;
|
||||||
use Webauthn\PublicKeyCredentialDescriptor;
|
use Webauthn\PublicKeyCredentialDescriptor;
|
||||||
|
use Webauthn\PublicKeyCredentialLoader;
|
||||||
use Webauthn\PublicKeyCredentialRequestOptions;
|
use Webauthn\PublicKeyCredentialRequestOptions;
|
||||||
use Webauthn\PublicKeyCredentialRpEntity;
|
use Webauthn\PublicKeyCredentialRpEntity;
|
||||||
|
use Webauthn\PublicKeyCredentialSource;
|
||||||
use Webauthn\PublicKeyCredentialUserEntity;
|
use Webauthn\PublicKeyCredentialUserEntity;
|
||||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||||
@ -65,7 +78,7 @@ class UserController extends Controller
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'allow' => true,
|
'allow' => true,
|
||||||
'actions' => ['logout', 'setup-two-factor', 'change-password', 'download-recovery-codes', 'remove-two-factor', 'set-theme', 'change-name'],
|
'actions' => ['logout', 'setup-two-factor', 'change-password', 'download-recovery-codes', 'remove-two-factor', 'set-theme', 'change-name', 'create-credential-options', 'create-credential', 'request-assertion-options', 'verify-assertion'],
|
||||||
'roles' => ['@'], // only logged-in user can do these ( admin included )
|
'roles' => ['@'], // only logged-in user can do these ( admin included )
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@ -85,6 +98,10 @@ class UserController extends Controller
|
|||||||
'verify-two-factor' => ['GET', 'POST'],
|
'verify-two-factor' => ['GET', 'POST'],
|
||||||
'set-theme' => ['POST'],
|
'set-theme' => ['POST'],
|
||||||
'change-name' => ['POST'],
|
'change-name' => ['POST'],
|
||||||
|
'create-credential-options' => ['GET'],
|
||||||
|
'create-credential' => ['POST'],
|
||||||
|
'request-assertion-options' => ['GET'],
|
||||||
|
'verify-assertion' => ['POST']
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
@ -570,12 +587,13 @@ class UserController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 创建公钥凭证选项
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws RandomException
|
* @throws RandomException
|
||||||
*/
|
*/
|
||||||
public function actionCreateCredentialOptions(): Response
|
public function actionCreateCredentialOptions(): Response
|
||||||
{
|
{
|
||||||
$id = Yii::$app->params['domain'] ?? null;
|
$id = Yii::$app->params['domain'];
|
||||||
$user = Yii::$app->user->identity;
|
$user = Yii::$app->user->identity;
|
||||||
|
|
||||||
$rpEntity = PublicKeyCredentialRpEntity::create(
|
$rpEntity = PublicKeyCredentialRpEntity::create(
|
||||||
@ -583,14 +601,10 @@ class UserController extends Controller
|
|||||||
$id
|
$id
|
||||||
);
|
);
|
||||||
|
|
||||||
$hash = md5(strtolower(trim($user->email)));
|
|
||||||
$gravatarUrl = "https://www.gravatar.com/avatar/$hash";
|
|
||||||
|
|
||||||
$userEntity = PublicKeyCredentialUserEntity::create(
|
$userEntity = PublicKeyCredentialUserEntity::create(
|
||||||
$user->username,
|
$user->username,
|
||||||
$user->id,
|
$user->id,
|
||||||
$user->name,
|
$user->name,
|
||||||
$gravatarUrl
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$challenge = random_bytes(16);
|
$challenge = random_bytes(16);
|
||||||
@ -609,47 +623,57 @@ class UserController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* 创建公钥凭证
|
||||||
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public function actionCreateCredential(): void
|
public function actionCreateCredential(): Response
|
||||||
{
|
{
|
||||||
$data = Yii::$app->request->post('publicKeyCredential');
|
$data = Yii::$app->request->getRawBody();
|
||||||
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
$attestationStatementSupportManager = AttestationStatementSupportManager::create();
|
||||||
|
$attestationStatementSupportManager->add(NoneAttestationStatementSupport::create());
|
||||||
|
$webauthnSerializerFactory = new WebauthnSerializerFactory($attestationStatementSupportManager);
|
||||||
|
$serializer = $webauthnSerializerFactory->create();
|
||||||
$publicKeyCredential = $serializer->deserialize($data, PublicKeyCredential::class, 'json');
|
$publicKeyCredential = $serializer->deserialize($data, PublicKeyCredential::class, 'json');
|
||||||
$authenticatorAttestationResponse = $publicKeyCredential->response;
|
$authenticatorAttestationResponse = $publicKeyCredential->response;
|
||||||
if (!$authenticatorAttestationResponse instanceof AuthenticatorAttestationResponse) {
|
if (!$authenticatorAttestationResponse instanceof AuthenticatorAttestationResponse) {
|
||||||
//e.g. process here with a redirection to the public key creation page.
|
return $this->asJson(['message' => 'Invalid response type']);
|
||||||
}
|
}
|
||||||
$attestationStatementSupportManager = AttestationStatementSupportManager::create();
|
|
||||||
$attestationStatementSupportManager->add(NoneAttestationStatementSupport::create());
|
$ceremonyStepManagerFactory = new CeremonyStepManagerFactory();
|
||||||
$extensionOutputCheckerHandler = ExtensionOutputCheckerHandler::create();
|
$ceremonyStepManager = $ceremonyStepManagerFactory->creationCeremony();
|
||||||
|
|
||||||
|
// PHP Deprecated:
|
||||||
|
// Since web-auth/webauthn-lib 4.8.0:
|
||||||
|
// The parameter "$attestationStatementSupportManager" is deprecated since 4.8.0 will be removed in 5.0.0.
|
||||||
|
// Please set a CheckAttestationFormatIsKnownAndValid object into CeremonyStepManager object instead.
|
||||||
|
// in /vendor/symfony/deprecation-contracts/function.php on line 25
|
||||||
|
// NMD, 这个问题在文档更新之前我是不会去解决的
|
||||||
$authenticatorAttestationResponseValidator = AuthenticatorAttestationResponseValidator::create(
|
$authenticatorAttestationResponseValidator = AuthenticatorAttestationResponseValidator::create(
|
||||||
$attestationStatementSupportManager,
|
$attestationStatementSupportManager,
|
||||||
null, //Deprecated Public Key Credential Source Repository. Please set null.
|
null, //Deprecated Public Key Credential Source Repository. Please set null.
|
||||||
null, //Deprecated Token Binding Handler. Please set null.
|
null, //Deprecated Token Binding Handler. Please set null.
|
||||||
$extensionOutputCheckerHandler
|
null,
|
||||||
|
null,
|
||||||
|
$ceremonyStepManager
|
||||||
);
|
);
|
||||||
|
|
||||||
$publicKeyCredentialCreationOptions = Yii::$app->session->get('publicKeyCredentialCreationOptions');
|
$publicKeyCredentialCreationOptions = Yii::$app->session->get('publicKeyCredentialCreationOptions');
|
||||||
try {
|
try {
|
||||||
$publicKeyCredentialSource = $authenticatorAttestationResponseValidator->check(
|
$publicKeyCredentialSource = $authenticatorAttestationResponseValidator->check( //response -> source
|
||||||
$authenticatorAttestationResponse,
|
$authenticatorAttestationResponse,
|
||||||
$publicKeyCredentialCreationOptions,
|
$publicKeyCredentialCreationOptions,
|
||||||
Yii::$app->params['domain'] ?? null
|
Yii::$app->params['domain']
|
||||||
);
|
);
|
||||||
// 创建一个PublicKeyCredentialSourceRepository对象
|
$publicKeyCredentialSourceRepository = new PublicKeyCredentialSourceRepository();
|
||||||
$publicKeyCredentialSourceRepository = new PublicKeyCredentialSource();
|
$publicKeyCredentialSourceRepository->saveCredential($publicKeyCredentialSource, 'test'); //receive source
|
||||||
|
return $this->asJson(['verified' => true]);
|
||||||
// 保存PublicKeyCredentialSource对象到数据库
|
|
||||||
$publicKeyCredentialSourceRepository->saveCredential($publicKeyCredentialSource);
|
|
||||||
|
|
||||||
Yii::$app->session->setFlash('success', '公钥凭证已创建');
|
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
//e.g. process here with a redirection to the public key creation page.
|
return $this->asJson(['message' => $e->getMessage(), 'verified' => false]);
|
||||||
//show error message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 请求验证选项
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws RandomException
|
* @throws RandomException
|
||||||
*/
|
*/
|
||||||
@ -657,12 +681,15 @@ class UserController extends Controller
|
|||||||
{
|
{
|
||||||
$user = Yii::$app->user->identity;
|
$user = Yii::$app->user->identity;
|
||||||
|
|
||||||
$publicKeyCredentialSourceRepository = new PublicKeyCredentialSource();
|
$publicKeyCredentialSourceRepository = new PublicKeyCredentialSourceRepository();
|
||||||
$registeredAuthenticators = $publicKeyCredentialSourceRepository->findAllForUserEntity($user);
|
$registeredAuthenticators = $publicKeyCredentialSourceRepository->findAllForUserEntity($user);
|
||||||
|
|
||||||
$allowedCredentials = array_map(
|
$allowedCredentials = array_map(
|
||||||
static function (PublicKeyCredentialSource $credential): PublicKeyCredentialDescriptor {
|
static function (PublicKeyCredentialSourceRepository $credential): PublicKeyCredentialDescriptor {
|
||||||
return $credential->getPublicKeyCredentialDescriptor();
|
$data = $credential->data;
|
||||||
|
$webauthnSerializerFactory = new WebauthnSerializerFactory(new AttestationStatementSupportManager());
|
||||||
|
$publicKeyCredentialSource = $webauthnSerializerFactory->create()->deserialize($data, PublicKeyCredentialSource::class, 'json');
|
||||||
|
return $publicKeyCredentialSource->getPublicKeyCredentialDescriptor();
|
||||||
},
|
},
|
||||||
$registeredAuthenticators
|
$registeredAuthenticators
|
||||||
);
|
);
|
||||||
@ -676,43 +703,55 @@ class UserController extends Controller
|
|||||||
return $this->asJson($publicKeyCredentialRequestOptions);
|
return $this->asJson($publicKeyCredentialRequestOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 验证断言
|
||||||
* @return void
|
* @return Response
|
||||||
|
* @throws \JsonException
|
||||||
*/
|
*/
|
||||||
public function actionVerifyAssertion(): void
|
public function actionVerifyAssertion(): Response
|
||||||
{
|
{
|
||||||
$data = Yii::$app->request->post('publicKeyCredential');
|
$data = Yii::$app->request->getRawBody();
|
||||||
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
|
||||||
|
$attestationStatementSupportManager = AttestationStatementSupportManager::create();
|
||||||
|
$attestationStatementSupportManager->add(NoneAttestationStatementSupport::create());
|
||||||
|
$webauthnSerializerFactory = new WebauthnSerializerFactory($attestationStatementSupportManager);
|
||||||
|
$serializer = $webauthnSerializerFactory->create();
|
||||||
|
|
||||||
$publicKeyCredential = $serializer->deserialize($data, PublicKeyCredential::class, 'json');
|
$publicKeyCredential = $serializer->deserialize($data, PublicKeyCredential::class, 'json');
|
||||||
|
|
||||||
$authenticatorAssertionResponse = $publicKeyCredential->response;
|
$authenticatorAssertionResponse = $publicKeyCredential->response;
|
||||||
if (!$authenticatorAssertionResponse instanceof AuthenticatorAssertionResponse) {
|
if (!$authenticatorAssertionResponse instanceof AuthenticatorAssertionResponse) {
|
||||||
//e.g. process here with a redirection to the public key login/MFA page.
|
return $this->asJson(['message' => 'Invalid response type']);
|
||||||
}
|
}
|
||||||
$publicKeyCredentialSourceRepository = new PublicKeyCredentialSource();
|
|
||||||
$publicKeyCredentialSource = $publicKeyCredentialSourceRepository->findOneByCredentialId(
|
$publicKeyCredentialSourceRepository = new PublicKeyCredentialSourceRepository();
|
||||||
$publicKeyCredential->rawId
|
$publicKeyCredentialSourceRepository1 = $publicKeyCredentialSourceRepository->findOneByCredentialId(
|
||||||
|
$publicKeyCredential->id
|
||||||
);
|
);
|
||||||
if ($publicKeyCredentialSource === null) {
|
if ($publicKeyCredentialSourceRepository1 === null) {
|
||||||
// Throw an exception if the credential is not found.
|
$this->asJson(['message' => 'Invalid credential']);
|
||||||
// It can also be rejected depending on your security policy (e.g. disabled by the user because of loss)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$PKCS = $webauthnSerializerFactory->create()->deserialize($publicKeyCredentialSourceRepository1->data, PublicKeyCredentialSource::class, 'json');
|
||||||
|
|
||||||
$authenticatorAssertionResponseValidator = AuthenticatorAssertionResponseValidator::create();
|
$authenticatorAssertionResponseValidator = AuthenticatorAssertionResponseValidator::create();
|
||||||
$publicKeyCredentialRequestOptions = Yii::$app->session->get('publicKeyCredentialRequestOptions');
|
$publicKeyCredentialRequestOptions = Yii::$app->session->get('publicKeyCredentialRequestOptions');
|
||||||
try {
|
try {
|
||||||
$publicKeyCredentialSource = $authenticatorAssertionResponseValidator->check(
|
$publicKeyCredentialSource = $authenticatorAssertionResponseValidator->check(
|
||||||
$publicKeyCredentialSource,
|
$PKCS,
|
||||||
$authenticatorAssertionResponse,
|
$authenticatorAssertionResponse,
|
||||||
$publicKeyCredentialRequestOptions,
|
$publicKeyCredentialRequestOptions,
|
||||||
Yii::$app->params['domain'] ?? null,
|
Yii::$app->params['domain'],
|
||||||
null //Deprecated Token Binding Handler. Please set null.
|
null //Deprecated Token Binding Handler. Please set null.
|
||||||
);
|
);
|
||||||
} catch (AuthenticatorResponseVerificationException $e) {
|
} catch (AuthenticatorResponseVerificationException $e) {
|
||||||
|
return $this->asJson(['message' => $e->getMessage(), 'verified' => false]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional, but highly recommended, you can save the credential source as it may be modified
|
// Optional, but highly recommended, you can save the credential source as it may be modified
|
||||||
// during the verification process (counter may be higher).
|
// during the verification process (counter may be higher).
|
||||||
$publicKeyCredentialSourceRepository->saveCredential($publicKeyCredentialSource);
|
$publicKeyCredentialSourceRepository1->saveCredential($publicKeyCredentialSource,'test');
|
||||||
|
return $this->asJson(['verified' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace app\models;
|
|
||||||
|
|
||||||
use Webauthn\AttestationStatement\AttestationStatementSupportManager;
|
|
||||||
use Webauthn\Denormalizer\WebauthnSerializerFactory;
|
|
||||||
use Webauthn\Exception\InvalidDataException;
|
|
||||||
use Yii;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the model class for table "public_key_credential_source".
|
|
||||||
*
|
|
||||||
* @property int $id 记录id
|
|
||||||
* @property int $user_id 对应的用户id
|
|
||||||
* @property string $public_key_credential_source PKCS
|
|
||||||
*
|
|
||||||
* @property User $user
|
|
||||||
*/
|
|
||||||
class PublicKeyCredentialSource extends \yii\db\ActiveRecord
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public static function tableName()
|
|
||||||
{
|
|
||||||
return 'public_key_credential_source';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function rules()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
[['user_id', 'public_key_credential_source'], 'required'],
|
|
||||||
[['user_id'], 'integer'],
|
|
||||||
[['public_key_credential_source'], 'string'],
|
|
||||||
[['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['user_id' => 'id']],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function attributeLabels()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'id' => 'ID',
|
|
||||||
'user_id' => 'User ID',
|
|
||||||
'public_key_credential_source' => 'Public Key Credential Source',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets query for [[User]].
|
|
||||||
*
|
|
||||||
* @return \yii\db\ActiveQuery
|
|
||||||
*/
|
|
||||||
public function getUser()
|
|
||||||
{
|
|
||||||
return $this->hasOne(User::class, ['id' => 'user_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户相关的所有公钥凭证
|
|
||||||
* @param User $user
|
|
||||||
* @return \Webauthn\PublicKeyCredentialSource[]
|
|
||||||
*/
|
|
||||||
public function findAllForUserEntity(User $user): array
|
|
||||||
{
|
|
||||||
$records = self::findAll(['user_id' => $user->id]);
|
|
||||||
$publicKeyCredentialSources = [];
|
|
||||||
$webauthnSerializerFactory = new WebauthnSerializerFactory(new AttestationStatementSupportManager());
|
|
||||||
foreach ($records as $record) {
|
|
||||||
$publicKeyCredentialSource = $webauthnSerializerFactory->create()->deserialize($record->public_key_credential_source, \Webauthn\PublicKeyCredentialSource::class, 'json');
|
|
||||||
$publicKeyCredentialSources[] = $publicKeyCredentialSource;
|
|
||||||
}
|
|
||||||
return $publicKeyCredentialSources;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从数据库中获取指定$id的记录,转为PublicKeyCredentialSource对象
|
|
||||||
* @param int $id
|
|
||||||
* @return \Webauthn\PublicKeyCredentialSource|null
|
|
||||||
*/
|
|
||||||
public function findOneByCredentialId(int $id): ?\Webauthn\PublicKeyCredentialSource
|
|
||||||
{
|
|
||||||
$record = self::findOne(['id' => $id]);
|
|
||||||
if ($record === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$webauthnSerializerFactory = new WebauthnSerializerFactory(new AttestationStatementSupportManager());
|
|
||||||
return $webauthnSerializerFactory->create()->deserialize($record->public_key_credential_source, \Webauthn\PublicKeyCredentialSource::class, 'json');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存PublicKeyCredentialSource对象到数据库
|
|
||||||
* @param \Webauthn\PublicKeyCredentialSource $PKCS
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function saveCredential(\Webauthn\PublicKeyCredentialSource $PKCS): void
|
|
||||||
{
|
|
||||||
// Create an instance of WebauthnSerializerFactory
|
|
||||||
$webauthnSerializerFactory = new WebauthnSerializerFactory(new AttestationStatementSupportManager());
|
|
||||||
|
|
||||||
// Serialize the PublicKeyCredentialSource object into a JSON string
|
|
||||||
$publicKeyCredentialSourceJson = $webauthnSerializerFactory->create()->serialize($PKCS, 'json');
|
|
||||||
|
|
||||||
// Save the JSON string to the public_key_credential_source field in the database
|
|
||||||
$this->public_key_credential_source = $publicKeyCredentialSourceJson;
|
|
||||||
$this->user_id = Yii::$app->user->id;
|
|
||||||
// Save the record to the database
|
|
||||||
$this->save();
|
|
||||||
}
|
|
||||||
}
|
|
108
models/PublicKeyCredentialSourceRepository.php
Normal file
108
models/PublicKeyCredentialSourceRepository.php
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use JsonException;
|
||||||
|
use Webauthn\PublicKeyCredentialSource;
|
||||||
|
use Yii;
|
||||||
|
use yii\db\ActiveQuery;
|
||||||
|
use yii\db\ActiveRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the model class for table "public_key_credential_source_repository".
|
||||||
|
*
|
||||||
|
* @property int $id 记录id
|
||||||
|
* @property int $user_id 对应的用户id
|
||||||
|
* @property string $name 标识名
|
||||||
|
* @property string $public_key_credential_id PKC_ID
|
||||||
|
* @property string $data PKC_DATA
|
||||||
|
*
|
||||||
|
* @property User $user
|
||||||
|
*/
|
||||||
|
class PublicKeyCredentialSourceRepository extends ActiveRecord
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function tableName(): string
|
||||||
|
{
|
||||||
|
return 'public_key_credential_source_repository';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['user_id', 'name', 'public_key_credential_id', 'data'], 'required'],
|
||||||
|
[['user_id'], 'integer'],
|
||||||
|
[['data'], 'string'],
|
||||||
|
[['name'], 'string', 'max' => 64],
|
||||||
|
[['public_key_credential_id'], 'string', 'max' => 255],
|
||||||
|
[['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['user_id' => 'id']],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function attributeLabels(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => 'ID',
|
||||||
|
'user_id' => 'User ID',
|
||||||
|
'name' => 'Name',
|
||||||
|
'public_key_credential_id' => 'Public Key Credential ID',
|
||||||
|
'data' => 'Data',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets query for [[User]].
|
||||||
|
*
|
||||||
|
* @return ActiveQuery
|
||||||
|
*/
|
||||||
|
public function getUser(): ActiveQuery
|
||||||
|
{
|
||||||
|
return $this->hasOne(User::class, ['id' => 'user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户相关的所有公钥凭证对象
|
||||||
|
* @param User $user
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function findAllForUserEntity(User $user): array
|
||||||
|
{
|
||||||
|
return self::findAll(['user_id' => $user->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据库中获取指定$id的记录对象
|
||||||
|
* @param string $PKC_ID
|
||||||
|
* @return PublicKeyCredentialSourceRepository|null
|
||||||
|
*/
|
||||||
|
public function findOneByCredentialId(string $PKC_ID): ?PublicKeyCredentialSourceRepository
|
||||||
|
{
|
||||||
|
return self::findOne(['public_key_credential_id' => $PKC_ID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存PublicKeyCredentialSource对象到数据库
|
||||||
|
* @param PublicKeyCredentialSource $PKCS
|
||||||
|
* @param string $name
|
||||||
|
* @return bool
|
||||||
|
* @throws JsonException
|
||||||
|
*/
|
||||||
|
public function saveCredential(PublicKeyCredentialSource $PKCS,string $name): bool
|
||||||
|
{
|
||||||
|
$jsonSerialize = $PKCS->jsonSerialize();
|
||||||
|
$this->public_key_credential_id = $jsonSerialize['publicKeyCredentialId'];
|
||||||
|
$publicKeyCredentialSourceJson = json_encode($jsonSerialize, JSON_THROW_ON_ERROR);
|
||||||
|
$this->data = $publicKeyCredentialSourceJson;
|
||||||
|
$this->name = $name;
|
||||||
|
$this->user_id = Yii::$app->user->id;
|
||||||
|
return $this->save();
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@ use yii\web\IdentityInterface;
|
|||||||
* @property string|null $vault_salt 保险箱加密密钥盐
|
* @property string|null $vault_salt 保险箱加密密钥盐
|
||||||
*
|
*
|
||||||
* @property CollectionTasks[] $collectionTasks
|
* @property CollectionTasks[] $collectionTasks
|
||||||
* @property PublicKeyCredentialSource[] $publicKeyCredentialSources
|
* @property PublicKeyCredentialSourceRepository[] $publicKeyCredentialSourcesRepository
|
||||||
* @property Share[] $shares
|
* @property Share[] $shares
|
||||||
*/
|
*/
|
||||||
class User extends ActiveRecord implements IdentityInterface
|
class User extends ActiveRecord implements IdentityInterface
|
||||||
@ -230,13 +230,13 @@ class User extends ActiveRecord implements IdentityInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets query for [[PublicKeyCredentialSources]].
|
* Gets query for [[PublicKeyCredentialSourcesRepository]].
|
||||||
*
|
*
|
||||||
* @return ActiveQuery
|
* @return ActiveQuery
|
||||||
*/
|
*/
|
||||||
public function getPublicKeyCredentialSources(): ActiveQuery
|
public function getPublicKeyCredentialSourcesRepository(): ActiveQuery
|
||||||
{
|
{
|
||||||
return $this->hasMany(PublicKeyCredentialSource::class, ['user_id' => 'id']);
|
return $this->hasMany(PublicKeyCredentialSourceRepository::class, ['user_id' => 'id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user