webauthn
This commit is contained in:
parent
286e447553
commit
691055b83e
|
@ -100,14 +100,15 @@ class WebauthnManager {
|
||||||
*
|
*
|
||||||
* @param string $dn DN
|
* @param string $dn DN
|
||||||
* @param bool $isSelfService is executed in self service
|
* @param bool $isSelfService is executed in self service
|
||||||
|
* @param array $extraExcludedKeys credentialIds that should be added to excluded keys
|
||||||
* @return PublicKeyCredentialCreationOptions registration object
|
* @return PublicKeyCredentialCreationOptions registration object
|
||||||
*/
|
*/
|
||||||
public function getRegistrationObject($dn, $isSelfService) {
|
public function getRegistrationObject($dn, $isSelfService, $extraExcludedKeys = array()) {
|
||||||
$rpEntity = $this->createRpEntry($isSelfService);
|
$rpEntity = $this->createRpEntry($isSelfService);
|
||||||
$userEntity = $this->getUserEntity($dn);
|
$userEntity = $this->getUserEntity($dn);
|
||||||
$challenge = $this->createChallenge();
|
$challenge = $this->createChallenge();
|
||||||
$credentialParameters = $this->getCredentialParameters();
|
$credentialParameters = $this->getCredentialParameters();
|
||||||
$excludedKeys = $this->getExcludedKeys($userEntity);
|
$excludedKeys = $this->getExcludedKeys($userEntity, $extraExcludedKeys);
|
||||||
$timeout = $this->getTimeout();
|
$timeout = $this->getTimeout();
|
||||||
$registrationObject = new PublicKeyCredentialCreationOptions(
|
$registrationObject = new PublicKeyCredentialCreationOptions(
|
||||||
$rpEntity,
|
$rpEntity,
|
||||||
|
@ -161,6 +162,18 @@ class WebauthnManager {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a public key credential loader.
|
||||||
|
*
|
||||||
|
* @return PublicKeyCredentialLoader public key credential loader
|
||||||
|
*/
|
||||||
|
public function createPublicKeyCredentialLoader() {
|
||||||
|
$decoder = $this->getCborDecoder();
|
||||||
|
$attestationSupportManager = $this->getAttestationSupportManager($decoder);
|
||||||
|
$attestationObjectLoader = $this->getAttestationObjectLoader($attestationSupportManager, $decoder);
|
||||||
|
return $this->getPublicKeyCredentialLoader($attestationObjectLoader, $decoder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the user entity for the registration.
|
* Returns the user entity for the registration.
|
||||||
*
|
*
|
||||||
|
@ -214,15 +227,19 @@ class WebauthnManager {
|
||||||
* Returns a list of all credential ids that are already registered.
|
* Returns a list of all credential ids that are already registered.
|
||||||
*
|
*
|
||||||
* @param PublicKeyCredentialUserEntity $user user data
|
* @param PublicKeyCredentialUserEntity $user user data
|
||||||
|
* @param array $extraExcludedKeys credentialIds that should be added to excluded keys
|
||||||
* @return PublicKeyCredentialDescriptor[] credential ids
|
* @return PublicKeyCredentialDescriptor[] credential ids
|
||||||
*/
|
*/
|
||||||
private function getExcludedKeys($user) {
|
private function getExcludedKeys($user, $extraExcludedKeys = array()) {
|
||||||
$keys = array();
|
$keys = array();
|
||||||
$repository = $this->getDatabase();
|
$repository = $this->getDatabase();
|
||||||
$credentialSources = $repository->findAllForUserEntity($user);
|
$credentialSources = $repository->findAllForUserEntity($user);
|
||||||
foreach ($credentialSources as $credentialSource) {
|
foreach ($credentialSources as $credentialSource) {
|
||||||
$keys[] = new PublicKeyCredentialDescriptor(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $credentialSource->getPublicKeyCredentialId());
|
$keys[] = new PublicKeyCredentialDescriptor(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $credentialSource->getPublicKeyCredentialId());
|
||||||
}
|
}
|
||||||
|
foreach ($extraExcludedKeys as $extraExcludedKey) {
|
||||||
|
$keys[] = new PublicKeyCredentialDescriptor(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $extraExcludedKey);
|
||||||
|
}
|
||||||
return $keys;
|
return $keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1620,7 +1620,9 @@ window.lam.webauthn.removeDevice = function(event) {
|
||||||
window.lam.webauthn.removeOwnDevice = function(event, isSelfService) {
|
window.lam.webauthn.removeOwnDevice = function(event, isSelfService) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const element = jQuery(event.currentTarget);
|
const element = jQuery(event.currentTarget);
|
||||||
const successCallback = function () {
|
let successCallback = null;
|
||||||
|
if (!isSelfService) {
|
||||||
|
successCallback = function () {
|
||||||
const form = jQuery("#webauthnform");
|
const form = jQuery("#webauthnform");
|
||||||
jQuery('<input>').attr({
|
jQuery('<input>').attr({
|
||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
|
@ -1629,6 +1631,7 @@ window.lam.webauthn.removeOwnDevice = function(event, isSelfService) {
|
||||||
}).appendTo(form);
|
}).appendTo(form);
|
||||||
form.submit();
|
form.submit();
|
||||||
};
|
};
|
||||||
|
}
|
||||||
let action = 'webauthnOwnDevices';
|
let action = 'webauthnOwnDevices';
|
||||||
if (isSelfService) {
|
if (isSelfService) {
|
||||||
action = action + '&selfservice=true&module=webauthn&scope=user';
|
action = action + '&selfservice=true&module=webauthn&scope=user';
|
||||||
|
@ -1706,21 +1709,44 @@ window.lam.webauthn.sendRemoveDeviceRequest = function(element, action, successC
|
||||||
* Registers a user's own webauthn device.
|
* Registers a user's own webauthn device.
|
||||||
*
|
*
|
||||||
* @param event click event
|
* @param event click event
|
||||||
|
* @param isSelfService runs in self service context
|
||||||
*/
|
*/
|
||||||
window.lam.webauthn.registerOwnDevice = function(event) {
|
window.lam.webauthn.registerOwnDevice = function(event, isSelfService) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const element = jQuery(event.target);
|
const element = jQuery(event.target);
|
||||||
const dn = element.data('dn');
|
const dn = element.data('dn');
|
||||||
const tokenValue = element.data('sec_token_value');
|
const tokenValue = element.data('sec_token_value');
|
||||||
const tokenName = element.data('sec_token_name');
|
|
||||||
const publicKey = element.data('publickey');
|
const publicKey = element.data('publickey');
|
||||||
const successCallback = function (publicKeyCredential) {
|
let successCallback = function (publicKeyCredential) {
|
||||||
const form = jQuery("#webauthnform");
|
const form = jQuery("#webauthnform");
|
||||||
const response = btoa(JSON.stringify(publicKeyCredential));
|
const response = btoa(JSON.stringify(publicKeyCredential));
|
||||||
const registrationData = jQuery('#registrationData');
|
const registrationData = jQuery('#registrationData');
|
||||||
registrationData.val(response);
|
registrationData.val(response);
|
||||||
form.submit();
|
form.submit();
|
||||||
};
|
};
|
||||||
|
if (isSelfService) {
|
||||||
|
successCallback = function (publicKeyCredential) {
|
||||||
|
const data = {
|
||||||
|
action: 'register',
|
||||||
|
jsonInput: '',
|
||||||
|
sec_token: tokenValue,
|
||||||
|
dn: dn,
|
||||||
|
credential: btoa(JSON.stringify(publicKeyCredential))
|
||||||
|
};
|
||||||
|
jQuery.ajax({
|
||||||
|
url: '../misc/ajax.php?selfservice=true&module=webauthn&scope=user',
|
||||||
|
method: 'POST',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
.done(function(jsonData) {
|
||||||
|
const resultDiv = jQuery('#webauthn_results');
|
||||||
|
resultDiv.html(jsonData.content);
|
||||||
|
})
|
||||||
|
.fail(function() {
|
||||||
|
console.log('Webauthn device registration failed');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
const errorCallback = function (error) {
|
const errorCallback = function (error) {
|
||||||
let errorDiv = jQuery('#generic-webauthn-error');
|
let errorDiv = jQuery('#generic-webauthn-error');
|
||||||
let buttonLabel = errorDiv.data('button');
|
let buttonLabel = errorDiv.data('button');
|
||||||
|
|
|
@ -88,7 +88,7 @@ $registrationJson = json_encode($registration);
|
||||||
$_SESSION['webauthn_registration'] = $registrationJson;
|
$_SESSION['webauthn_registration'] = $registrationJson;
|
||||||
$registerButton->addDataAttribute('publickey', $registrationJson);
|
$registerButton->addDataAttribute('publickey', $registrationJson);
|
||||||
$registerButton->setIconClass('createButton');
|
$registerButton->setIconClass('createButton');
|
||||||
$registerButton->setOnClick('window.lam.webauthn.registerOwnDevice(event);');
|
$registerButton->setOnClick('window.lam.webauthn.registerOwnDevice(event, false);');
|
||||||
$buttonGroup->addElement($registerButton);
|
$buttonGroup->addElement($registerButton);
|
||||||
$buttonGroup->addElement(new htmlSpacer('1rem', null));
|
$buttonGroup->addElement(new htmlSpacer('1rem', null));
|
||||||
$reloadButton = new htmlButton('reload', _('Reload'));
|
$reloadButton = new htmlButton('reload', _('Reload'));
|
||||||
|
|
Loading…
Reference in New Issue