You've already forked lubo_comment_query
							
							
		
			
				
	
	
		
			172 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Http\Controllers;
 | |
| 
 | |
| use App\WebAuthn\Repository\PublicKeyCredentialSourceRepositoryImpl;
 | |
| use App\WebAuthn\WebAuthnService;
 | |
| use Cose\Algorithm\Manager;
 | |
| use Cose\Algorithm\Signature\ECDSA\ES256;
 | |
| use Cose\Algorithm\Signature\RSA\RS256;
 | |
| use Cose\Algorithms;
 | |
| use GuzzleHttp\Psr7\ServerRequest;
 | |
| use Illuminate\Http\Request;
 | |
| use Illuminate\Routing\Controller as BaseController;
 | |
| use Illuminate\Support\Facades\Auth;
 | |
| use Webauthn\AttestationStatement\AttestationObjectLoader;
 | |
| use Webauthn\AttestationStatement\AttestationStatementSupportManager;
 | |
| use Webauthn\AttestationStatement\NoneAttestationStatementSupport;
 | |
| use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler;
 | |
| use Webauthn\AuthenticatorAssertionResponse;
 | |
| use Webauthn\AuthenticatorAssertionResponseValidator;
 | |
| use Webauthn\AuthenticatorAttestationResponse;
 | |
| use Webauthn\AuthenticatorAttestationResponseValidator;
 | |
| use Webauthn\AuthenticatorSelectionCriteria;
 | |
| use Webauthn\PublicKeyCredentialCreationOptions;
 | |
| use Webauthn\PublicKeyCredentialLoader;
 | |
| use Webauthn\PublicKeyCredentialParameters;
 | |
| use Webauthn\PublicKeyCredentialRequestOptions;
 | |
| use Webauthn\PublicKeyCredentialRpEntity;
 | |
| use Webauthn\PublicKeyCredentialSourceRepository;
 | |
| use Webauthn\PublicKeyCredentialUserEntity;
 | |
| use Webauthn\TokenBinding\IgnoreTokenBindingHandler;
 | |
| 
 | |
| class UserWebAuthnController extends BaseController
 | |
| {
 | |
|     private $attestationStatementSupportManager = null;
 | |
| 
 | |
|     public function webauthn_login(Request $request)
 | |
|     {
 | |
|         return view("user.webauthn.login");
 | |
|     }
 | |
| 
 | |
|     public function register_options(Request $request): PublicKeyCredentialCreationOptions
 | |
|     {
 | |
|         $userEntity = new PublicKeyCredentialUserEntity(
 | |
|             $request->user("web")->name,
 | |
|             $request->user("web")->id,
 | |
|             $request->user("web")->name,
 | |
|         );
 | |
|         $challenge = random_bytes(16);
 | |
|         $request->session()->put("webauthn_register_challenge", $challenge);
 | |
|         return WebAuthnService::createRequestOptions($userEntity, $challenge);
 | |
|     }
 | |
| 
 | |
|     public function login_options(Request $request): PublicKeyCredentialRequestOptions
 | |
|     {
 | |
|         $challenge = random_bytes(32);
 | |
|         $request->session()->put("webauthn_login_challenge", $challenge);
 | |
|         $publicKeyCredentialRequestOptions = new PublicKeyCredentialRequestOptions(
 | |
|             $challenge
 | |
|         );
 | |
|         $publicKeyCredentialRequestOptions->setUserVerification(
 | |
|             PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_REQUIRED
 | |
|         );
 | |
|         $publicKeyCredentialRequestOptions->allowCredentials([]);
 | |
|         return $publicKeyCredentialRequestOptions;
 | |
|     }
 | |
| 
 | |
|     public function register_validate(Request $request)
 | |
|     {
 | |
|         if (!$request->session()->has("webauthn_register_challenge")) {
 | |
|             ///
 | |
|         }
 | |
|         $publicKeyCredential = $this->get_public_key_credential_loader()->loadArray($request->json()->all());
 | |
|         $authenticatorAttestationResponse = $publicKeyCredential->getResponse();
 | |
|         if (!$authenticatorAttestationResponse instanceof AuthenticatorAttestationResponse) {
 | |
|             //e.g. process here with a redirection to the public key creation page.
 | |
|         }
 | |
|         $userEntity = new PublicKeyCredentialUserEntity(
 | |
|             $request->user("web")->name,
 | |
|             $request->user("web")->id,
 | |
|             $request->user("web")->name,
 | |
|         );
 | |
|         $challenge = $request->session()->remove("webauthn_register_challenge");
 | |
|         $publicKeyCredentialCreationOptions = WebAuthnService::createRequestOptions($userEntity, $challenge);
 | |
|         $publicKeyCredentialSource = $this->get_authn_attestation_response_validator()->check(
 | |
|             $authenticatorAttestationResponse,
 | |
|             $publicKeyCredentialCreationOptions,
 | |
|             ServerRequest::fromGlobals(),
 | |
|             ["localhost"]
 | |
|         );
 | |
|         $this->get_pub_key_cred_source_repository()->saveCredentialSource($publicKeyCredentialSource);
 | |
|         return $publicKeyCredentialSource;
 | |
|     }
 | |
| 
 | |
|     public function login_validate(Request $request)
 | |
|     {
 | |
|         if (!$request->session()->has("webauthn_login_challenge")) {
 | |
|             ///
 | |
|         }
 | |
|         $publicKeyCredentialRequestOptions = new PublicKeyCredentialRequestOptions(
 | |
|             $request->session()->remove("webauthn_login_challenge")
 | |
|         );
 | |
|         $publicKeyCredential = $this->get_public_key_credential_loader()->loadArray($request->json()->all());
 | |
|         $authenticatorAssertionResponse = $publicKeyCredential->getResponse();
 | |
|         if (!$authenticatorAssertionResponse instanceof AuthenticatorAssertionResponse) {
 | |
|             //e.g. process here with a redirection to the public key login/MFA page.
 | |
|         }
 | |
|         try {
 | |
|             $publicKeyCredentialSource = $this->get_authn_assertion_response_validator()->check(
 | |
|                 $publicKeyCredential->getRawId(),
 | |
|                 $authenticatorAssertionResponse,
 | |
|                 $publicKeyCredentialRequestOptions,
 | |
|                 ServerRequest::fromGlobals(),
 | |
|                 $authenticatorAssertionResponse->getUserHandle(),
 | |
|                 ["localhost"]
 | |
|             );
 | |
|         } catch (\Throwable $e) {
 | |
|             return redirect(route("login"));
 | |
|         }
 | |
|         Auth::loginUsingId($publicKeyCredentialSource->getUserHandle());
 | |
|         return redirect()->intended();
 | |
|     }
 | |
| 
 | |
|     private function get_authn_attestation_response_validator(): AuthenticatorAttestationResponseValidator
 | |
|     {
 | |
|         $authenticatorAttestationResponseValidator = new AuthenticatorAttestationResponseValidator(
 | |
|             $this->get_attestation_stmt_sup_mgr(),
 | |
|             WebAuthnService::getPublicKeyCredentialSourceRepository(),
 | |
|             new IgnoreTokenBindingHandler(),
 | |
|             new ExtensionOutputCheckerHandler()
 | |
|         );
 | |
|         return $authenticatorAttestationResponseValidator;
 | |
|     }
 | |
| 
 | |
|     private function get_authn_assertion_response_validator(): AuthenticatorAssertionResponseValidator
 | |
|     {
 | |
|         $algorithmManager = new Manager();
 | |
|         $algorithmManager->add(new ES256());
 | |
|         $algorithmManager->add(new RS256());
 | |
|         $authenticatorAssertionResponseValidator = new AuthenticatorAssertionResponseValidator(
 | |
|             WebAuthnService::getPublicKeyCredentialSourceRepository(),
 | |
|             new IgnoreTokenBindingHandler(),
 | |
|             new ExtensionOutputCheckerHandler(),
 | |
|             $algorithmManager
 | |
|         );
 | |
|         return $authenticatorAssertionResponseValidator;
 | |
|     }
 | |
| 
 | |
|     private function get_public_key_credential_loader(): PublicKeyCredentialLoader
 | |
|     {
 | |
|         $publicKeyCredentialLoader = new PublicKeyCredentialLoader(
 | |
|             $this->get_attestation_loader()
 | |
|         );
 | |
|         return $publicKeyCredentialLoader;
 | |
|     }
 | |
| 
 | |
|     private function get_attestation_loader(): AttestationObjectLoader
 | |
|     {
 | |
|         $attestationObjectLoader = new AttestationObjectLoader($this->get_attestation_stmt_sup_mgr());
 | |
|         return $attestationObjectLoader;
 | |
|     }
 | |
| 
 | |
|     private function get_attestation_stmt_sup_mgr()
 | |
|     {
 | |
|         if ($this->attestationStatementSupportManager === null) {
 | |
|             $this->attestationStatementSupportManager = new AttestationStatementSupportManager();
 | |
|             $this->attestationStatementSupportManager->add(new NoneAttestationStatementSupport());
 | |
|         }
 | |
|         return $this->attestationStatementSupportManager;
 | |
|     }
 | |
| }
 |