add support for webauthn

This commit is contained in:
Uwe Steinmann 2020-04-23 21:09:00 +02:00
parent 226c4f2c5a
commit 2cde6f01b4

View File

@ -97,6 +97,115 @@ $(document).ready( function() {
}, },
}); });
}); });
function webauthnAuthenticate(key, cb){
var pk = JSON.parse(key);
var originalChallenge = pk.challenge;
pk.challenge = new Uint8Array(pk.challenge);
pk.allowCredentials.forEach(function(k, idx){
pk.allowCredentials[idx].id = new Uint8Array(k.id);
});
/* ask the browser to prompt the user */
navigator.credentials.get({publicKey: pk})
.then(function(aAssertion) {
// console.log("Credentials.Get response: ", aAssertion);
var ida = [];
(new Uint8Array(aAssertion.rawId)).forEach(function(v){ ida.push(v); });
var cd = JSON.parse(String.fromCharCode.apply(null,
new Uint8Array(aAssertion.response.clientDataJSON)));
var cda = [];
(new Uint8Array(aAssertion.response.clientDataJSON)).forEach(function(v){ cda.push(v); });
var ad = [];
(new Uint8Array(aAssertion.response.authenticatorData)).forEach(function(v){ ad.push(v); });
var sig = [];
(new Uint8Array(aAssertion.response.signature)).forEach(function(v){ sig.push(v); });
var info = {
type: aAssertion.type,
originalChallenge: originalChallenge,
rawId: ida,
response: {
authenticatorData: ad,
clientData: cd,
clientDataJSONarray: cda,
signature: sig
}
};
cb(true, JSON.stringify(info));
})
.catch(function (aErr) {
if (("name" in aErr) && (aErr.name == "AbortError" || aErr.name == "NS_ERROR_ABORT" ||
aErr.name == "NotAllowedError")) {
cb(false, 'abort');
} else {
cb(false, aErr.toString());
}
});
}
$(function(){
$('#webauthnlogin').click(function(ev){
var self = $(this);
ev.preventDefault();
$.ajax({url: '../op/op.Login.php',
method: 'POST',
data: {action: 'preparelogin', login: $('#loginusername').val()},
dataType: 'json',
success: function(j){
/* activate the key and get the response */
webauthnAuthenticate(j.challenge, function(success, info){
if (success) {
$.ajax({url: '../op/op.Login.php',
method: 'POST',
data: {action: 'login', login: $('#loginusername').val(), logininfo: info},
dataType: 'json',
success: function(j){
noty({
text: 'login completed successfully',
type: 'success',
dismissQueue: true,
layout: 'topRight',
theme: 'defaultTheme',
_timeout: 1500,
});
window.location = j;
},
error: function(xhr, status, error){
noty({
text: 'login failed: '+error+": "+xhr.responseText,
type: 'error',
dismissQueue: true,
layout: 'topRight',
theme: 'defaultTheme',
_timeout: 1500,
});
}
});
} else {
noty({
text: info,
type: 'error',
dismissQueue: true,
layout: 'topRight',
theme: 'defaultTheme',
_timeout: 1500,
});
}
});
},
error: function(xhr, status, error){
noty({
text: "couldn't initiate login: "+error+": "+xhr.responseText,
type: 'error',
dismissQueue: true,
layout: 'topRight',
theme: 'defaultTheme',
_timeout: 1500,
});
}
});
});
});
<?php <?php
} /* }}} */ } /* }}} */
@ -121,7 +230,7 @@ $(document).ready( function() {
$this->errorMsg(htmlspecialchars($msg)); $this->errorMsg(htmlspecialchars($msg));
?> ?>
<?php $this->contentContainerStart(); ?> <?php $this->contentContainerStart(); ?>
<form class="form-horizontal" action="../op/op.Login.php" method="post" name="form1" id="form"> <form class="form-horizontal" action="../op/op.Login.php" method="post" name="form1" id="loginform">
<?php <?php
if ($refer) { if ($refer) {
echo "<input type='hidden' name='referuri' value='".sanitizeString($refer)."'/>"; echo "<input type='hidden' name='referuri' value='".sanitizeString($refer)."'/>";
@ -131,7 +240,7 @@ $(document).ready( function() {
array( array(
'element'=>'input', 'element'=>'input',
'type'=>'text', 'type'=>'text',
'id'=>'login', 'id'=>'loginusername',
'name'=>'login', 'name'=>'login',
'placeholder'=>'login', 'placeholder'=>'login',
'autocomplete'=>'off', 'autocomplete'=>'off',
@ -187,10 +296,15 @@ $(document).ready( function() {
$html $html
); );
} }
echo '<div class="control-group">';
$this->formSubmit(getMLText('submit_login')); $this->formSubmit(getMLText('submit_login'));
echo '</div>';
?> ?>
</form> </form>
<?php <?php
echo '<div class="control-group">';
$this->formSubmit(getMLText('submit_webauthn_login'), 'webauthnlogin');
echo '</div>';
$this->contentContainerEnd(); $this->contentContainerEnd();
$tmpfoot = array(); $tmpfoot = array();
if ($enableguestlogin) if ($enableguestlogin)