https://slides.com/elpete/itb2024-cbsecurity-passkeys
Competition
Who has the most Passkeys?
What this talk is
- An intro to passkeys and passwordless authentication
- Overview of the CBSecurity Passkeys module
- Demo of integrating passkeys into a new ColdBox application
What this talk isn't
- Introduction to CBSecurity
- Deep Dive of all Passkeys options
- Framework-agnostic (requires CBSecurity and ColdBox)
Authentication
-
Username and Password
-
Single-use Links (Email login)
-
Two Factor Authentication
-
Security Keys or Cards
Authentication
The Problems with Passwords
Source: The United States of P@ssw0rd$
Source: The United States of P@ssw0rd$
Source: The United States of P@ssw0rd$
Source: The United States of P@ssw0rd$
So what's the solution?
Password Rules?
Password Manager?
Source: The United States of P@ssw0rd$ (2019)
Friction
Phishing
How do Passkeys solve the problems with Passwords?
- No passwords to remember
- Unique passkey per site
- Two-factor by default
- Cannot be phished
- Built on Public / Private key pairs
Benefits of Passkeys
Webauthn
Passkeys
Webauthn
Passkeys
==
Techincal Name
Marketing
Webauthn
Passkeys
!==
Adoption
In less than a year, passkeys have been used to authenticate people more than 1 billion times across over 400 million Google Accounts.
Paid Solutions
The "Ortus Solutions"
CBSecurity Passkeys
SUPER COOL LOGO
COMING SOON!
CBSecurity Passkeys
- Builds on CBSecurity and CBAuth
- Uses your Authentication Provider to log users in
- Requires CBSecurity 3+ and CBAuth 6.1+
- Built on top of webauthn-server-core by Yubico
CBSecurity Passkeys
- All required Java dependencies in a single jar
- Handlers for registering new Passkeys and authenticating using Passkeys
- JavaScript resources for registering new Passkeys and authenticating using Passkeys
- Required interface for storing and retrieving Passkeys from an external store (e.g. database)
Provides:
Installation
box install cbsecurity-passkeys
component {
this.javaSettings = {
loadPaths : [ expandPath( "./modules/cbsecurity-passkeys/lib" ) ],
loadColdFusionClassPath : true,
reloadOnChange : false
};
}
Load Java Dependencies
schema.create( "cbsecurity_passkeys", ( t ) => {
t.increments( "id" );
t.unsignedInteger( "userId" ).references( "id" ).onTable( "users" );
t.raw( "credentialId BLOB" );
t.raw( "publicKey BLOB" );
t.unsignedInteger( "signCount" );
t.bit( "backupEligible" );
t.bit( "backupState" );
t.raw( "attestationObject BLOB" );
t.text( "clientDataJSON" );
t.datetime( "lastUsedTimestamp" ).nullable();
} );
(OPTIONAL)
Migrate Database Table
Configuration
Module Settings
moduleSettings = {
"cbsecurity-passkeys" : {
// WireBox mapping to the component
// implementing the ICredentialRepository interface
"credentialRepositoryMapping": "",
// The identifier for the relying party (your application)
"relyingPartyId" : CGI.SERVER_NAME,
// The display name for the relying party (your application)
"relyingPartyName" : controller.getSetting( "appName" ),
// The allowed origins to send you Passkeys.
// Defaults to the server name, if empty.
// (Non-standard ports need to be specified explicitly)
"allowedOrigins": []
}
};
ICredentialRepository
ICredentialRepository
- Defines the methods needed to register and authenticate Passkeys
- An example implementation using Quick is available in the module.
resources/examples/Passkey.cfc
ICredentialRepository
public string function getUsernameForUser( required any user ) {}
public string function getDisplayNameForUser( required any user ) {}
public any function getUserHandleForUser( required any user ) {}
public array function getCredentialIdsForUsername( required string username ) {}
public any function getUserHandleForUsername( required string username ) {}
public string function getUsernameForUserHandle( required any userHandle ) {}
public struct function lookup( required any credentialId, required any userHandle ) {}
public array function lookupAll( required any credentialId ) {}
public void function storeCredentialForUser( /* ... */ ) {}
public void function updateCredentialForUser( /* ... */ ) {}
Usage
Server-side
Implement ICredentialRepository
Client-side
Detecting Passkey Support
<cfoutput>
<div>
<div class="jumbotron mt-sm-5 p-4">
<h1>Passkey Demo</h1>
</div>
<form id="passkey-form" action="#event.buildLink( "passkeys.new" )#" method="GET" style="display: none;">
<button type="submit" class="btn btn-primary">Create Passkey</button>
</form>
</div>
</cfoutput>
<script src="/modules_app/cbsecurity-passkeys/includes/js/passkeys.js"></script>
<script>
if (window.cbSecurity.passkeys.isSupported()) {
document.getElementById("passkey-form").style.display = "block";
}
</script>
Registering Passkeys
<cfoutput>
<div>
<div class="jumbotron mt-sm-5 p-4">
<h1>Creating a Passkey...</h1>
</div>
</div>
<script src="/modules/cbsecurity-passkeys/includes/passkeys.js"></script>
<script>
window.cbSecurity.passkeys.register();
</script>
</cfoutput>
Logging in with a Passkey
<cfoutput>
<h3>Log In</h3>
<small>or <a href="#event.buildLink( "registrations.new" )#">register for an account</a></small>
<hr />
<form id="loginForm" method="POST" action="#event.buildLink( "login" )#">
<input type="hidden" name="_token" value="#csrfGenerateToken()#" />
<div class="form-group">
<label for="username">Email Address:</label>
<input name="email" type="text" class="form-control" id="email" autocomplete="username webauthn" />
</div>
<div class="form-group">
<label for="password">Password:</label>
<input name="password" type="password" class="form-control" id="password" autocomplete="current-password webauthn"/>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Log In</button>
</div>
</form>
<button id="passkeyLoginButton" type="button" class="btn btn-primary" style="display: none;">Log in with Passkey</button>
</cfoutput>
<script src="/modules_app/cbsecurity-passkeys/includes/passkeys.js"></script>
<script>
if ( window.cbSecurity.passkeys.isSupported() ) {
const passkeyLoginButton = document.getElementById( "passkeyLoginButton" );
passkeyLoginButton.style.display = "block";
passkeyLoginButton.addEventListener( "click", function() {
window.cbSecurity.passkeys.login(document.forms.loginForm.email.value);
});
}
</script>
Demo
Competition Results
So who has the most Passkeys?
ITB 2024 — CBSecurity Passkeys
By Eric Peterson
ITB 2024 — CBSecurity Passkeys
- 151