Skip to content

Commit

Permalink
webauthn.js methods encapsulation
Browse files Browse the repository at this point in the history
  • Loading branch information
maximthomas committed May 17, 2024
1 parent c7426c4 commit 329661e
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Schema
serviceHierarchy="/DSAMEConfig/authentication/sunAMAuthWebAuthnAuthenticationService"
i18nFileName="amAuthWebAuthn"
revisionNumber="1"
revisionNumber="2"
i18nKey="org.openidentityplatform.openam.authentication.modules.webauthn.WebAuthnAuthentication.description"
resourceName="webauthnauth">

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Schema
serviceHierarchy="/DSAMEConfig/authentication/sunAMAuthWebAuthnRegistrationService"
i18nFileName="amAuthWebAuthn"
revisionNumber="1"
revisionNumber="2"
i18nKey="org.openidentityplatform.openam.authentication.modules.webauthn.WebAuthnRegistration.description"
resourceName="webauthnreg">

Expand Down Expand Up @@ -78,9 +78,9 @@
syntax="string"
i18nKey="org.openidentityplatform.openam.authentication.modules.webauthn.WebAuthnRegistration.attestation">
<ChoiceValues>
<ChoiceValue i18nKey="none">None</ChoiceValue>
<ChoiceValue i18nKey="indirect">Indirect</ChoiceValue>
<ChoiceValue i18nKey="direct">Direct</ChoiceValue>
<ChoiceValue i18nKey="none">none</ChoiceValue>
<ChoiceValue i18nKey="indirect">indirect</ChoiceValue>
<ChoiceValue i18nKey="direct">direct</ChoiceValue>
</ChoiceValues>
<DefaultValues>
<Value>none</Value>
Expand All @@ -91,9 +91,9 @@
syntax="string"
i18nKey="org.openidentityplatform.openam.authentication.modules.webauthn.WebAuthnRegistration.authType">
<ChoiceValues>
<ChoiceValue i18nKey="unspecified">Unspecified</ChoiceValue>
<ChoiceValue i18nKey="cross-platform">Cross-platform</ChoiceValue>
<ChoiceValue i18nKey="platform">Platform</ChoiceValue>
<ChoiceValue i18nKey="unspecified">unspecified</ChoiceValue>
<ChoiceValue i18nKey="cross-platform">cross-platform</ChoiceValue>
<ChoiceValue i18nKey="platform">platform</ChoiceValue>
</ChoiceValues>
<DefaultValues>
<Value>unspecified</Value>
Expand Down
210 changes: 106 additions & 104 deletions openam-server-only/src/main/webapp/assets/js/webauthn.js
Original file line number Diff line number Diff line change
@@ -1,117 +1,119 @@
function bufferDecode(value) {
return Uint8Array.from(atob(value), c => c.charCodeAt(0));
}

function bufferEncode(bytes) {
let binary = ''
const len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
function WebAuthn() {
function bufferDecode(value) {
return Uint8Array.from(atob(value), c => c.charCodeAt(0));
}
return window.btoa( binary ).replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "")
}

function processRegistrationChallenge() {
var challengeStr = getRegistrationChallenge();
var challenge = JSON.parse(challengeStr);
challenge.challenge = bufferDecode(challenge.challenge.value);
challenge.user.id = bufferDecode(challenge.user.id);
navigator.credentials.create({
publicKey: challenge,
}).then((credential) => {
register(credential);
}).catch((e) => {
console.log(e.toString());

function bufferEncode(bytes) {
let binary = ''
const len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
);
}
return window.btoa(binary).replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "")
}

function getRegistrationChallenge() {
var querySelector = ".TextOutputCallback_0";
if(isXUI()) {
querySelector = "#callback_3";
function processRegistrationChallenge() {
var challengeStr = getRegistrationChallenge();
var challenge = JSON.parse(challengeStr);
challenge.challenge = bufferDecode(challenge.challenge.value);
challenge.user.id = bufferDecode(challenge.user.id);
navigator.credentials.create({
publicKey: challenge,
}).then((credential) => {
register(credential);
}).catch((e) => {
console.log(e.toString());
}
);
}

function getRegistrationChallenge() {
var querySelector = ".TextOutputCallback_0";
if (isXUI()) {
querySelector = "#callback_1";
}
return document.querySelector(querySelector).innerText;
}
return document.querySelector(querySelector).innerText;
}

function isXUI() {
return !!window.requirejs;
}

function register(credential) {
var idToken1Sel = "IDToken1";
var idToken2Sel = "IDToken2";
var idToken3Sel = "IDToken3";
var buttonSel = "[name='Login.Submit']";
if(isXUI()) {
idToken1Sel = "idToken1";
idToken2Sel = "idToken2";
idToken3Sel = "idToken3";
buttonSel = "#loginButton_0";

function isXUI() {
return !!window.requirejs;
}
document.getElementById(idToken1Sel).value = credential.id;
document.getElementById(idToken2Sel).value = bufferEncode( new Uint8Array(credential.response.attestationObject));
document.getElementById(idToken3Sel).value = bufferEncode( new Uint8Array(credential.response.clientDataJSON));
document.querySelector(buttonSel).click();
}


function processAuthenticationChallenge() {
var credentialsStr = getAuthenticationChallenge();
var credentials = JSON.parse(credentialsStr);
credentials.challenge = bufferDecode(credentials.challenge.value);
credentials.allowCredentials.forEach(function (allowCredential, i) {
allowCredential.id = bufferDecode(allowCredential.id);

function register(credential) {
var idToken1Sel = "IDToken1";
var buttonSel = "[name='Login.Submit']";
if (isXUI()) {
idToken1Sel = "idToken1";
buttonSel = "#loginButton_0";
}

var credentials = {
credentialId: credential.id,
attestationObject: bufferEncode(new Uint8Array(credential.response.attestationObject)),
clientDataJSON: bufferEncode(new Uint8Array(credential.response.clientDataJSON)),
}
);

navigator.credentials.get({
publicKey: credentials,
}).then((assertion) => {
assert(assertion);
}).catch((e) => {
console.log(e.toString());
});
}

function assert(assertion) {

var authenticatorData = new Uint8Array(assertion.response.authenticatorData);
var clientDataJSON = new Uint8Array(assertion.response.clientDataJSON);
var signature = new Uint8Array(assertion.response.signature);
var userHandle = new Uint8Array(assertion.response.userHandle);

var idToken1Sel = "IDToken1";
var idToken2Sel = "IDToken2";
var idToken3Sel = "IDToken3";
var idToken4Sel = "IDToken4";
var idToken5Sel = "IDToken5";
var buttonSel = "[name='Login.Submit']";
if(isXUI()) {
idToken1Sel = "idToken1";
idToken2Sel = "idToken2";
idToken3Sel = "idToken3";
idToken4Sel = "idToken4";
idToken5Sel = "idToken5";
buttonSel = "#loginButton_0";

document.getElementById(idToken1Sel).value = JSON.stringify(credentials);
document.querySelector(buttonSel).click();
}


function processAuthenticationChallenge() {
var credentialsStr = getAuthenticationChallenge();
var credentials = JSON.parse(credentialsStr);
credentials.challenge = bufferDecode(credentials.challenge.value);
credentials.allowCredentials.forEach(function (allowCredential, i) {
allowCredential.id = bufferDecode(allowCredential.id);
}
);

navigator.credentials.get({
publicKey: credentials,
}).then((assertion) => {
assert(assertion);
}).catch((e) => {
console.log(e.toString());
});
}

document.getElementById(idToken1Sel).value = assertion.id;
document.getElementById(idToken2Sel).value = bufferEncode( new Uint8Array(authenticatorData));
document.getElementById(idToken3Sel).value = bufferEncode( new Uint8Array(clientDataJSON));
document.getElementById(idToken4Sel).value = bufferEncode( new Uint8Array(signature));
document.getElementById(idToken5Sel).value = bufferEncode(userHandle);
function assert(assertion) {

var authenticatorData = new Uint8Array(assertion.response.authenticatorData);
var clientDataJSON = new Uint8Array(assertion.response.clientDataJSON);
var signature = new Uint8Array(assertion.response.signature);
var userHandle = new Uint8Array(assertion.response.userHandle);

var idToken1Sel = "IDToken1";
var buttonSel = "[name='Login.Submit']";
if (isXUI()) {
idToken1Sel = "idToken1";
buttonSel = "#loginButton_0";
}

var credentials = {
assertionId: assertion.id,
authenticatorData: bufferEncode(new Uint8Array(authenticatorData)),
clientDataJSON: bufferEncode(new Uint8Array(clientDataJSON)),
signature: bufferEncode(new Uint8Array(signature)),
userHandle: bufferEncode(userHandle),
}

document.querySelector(buttonSel).click();
document.getElementById(idToken1Sel).value = JSON.stringify(credentials);
document.querySelector(buttonSel).click();

}
}

function getAuthenticationChallenge() {
var querySelector = ".TextOutputCallback_0";
if(isXUI()) {
querySelector = "#callback_5";
function getAuthenticationChallenge() {
var querySelector = ".TextOutputCallback_0";
if (isXUI()) {
querySelector = "#callback_1";
}
return document.querySelector(querySelector).innerText;
}
return {
processRegistrationChallenge: processRegistrationChallenge,
processAuthenticationChallenge: processAuthenticationChallenge,
}
return document.querySelector(querySelector).innerText;
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@
</div>
</body>
<script>
processAuthenticationChallenge();
WebAuthn().processAuthenticationChallenge();
</script>
</jato:useViewBean>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@
</div>
</body>
<script>
processRegistrationChallenge();
WebAuthn().processRegistrationChallenge();
</script>
</jato:useViewBean>
</html>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="container">
<script>
require(['../assets/js/webauthn.js'], function () {
processAuthenticationChallenge();
WebAuthn().processAuthenticationChallenge();
});
</script>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="container">
<script>
require(['../assets/js/webauthn.js'], function () {
processRegistrationChallenge();
WebAuthn().processRegistrationChallenge();
});
</script>

Expand Down

0 comments on commit 329661e

Please sign in to comment.