Skip to content

Commit

Permalink
Merge pull request #175 from EmilioCristalli/relying-party
Browse files Browse the repository at this point in the history
Use global `WebAuthn::Credential` instead of custom `WebAuthn::RelyingParty`
  • Loading branch information
EmilioCristalli authored Oct 11, 2024
2 parents b7eaeb4 + 10e9812 commit 9f00511
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 44 deletions.
8 changes: 0 additions & 8 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,4 @@ def current_user
User.find_by(id: session[:user_id])
end
end

def relying_party
@relying_party ||=
WebAuthn::RelyingParty.new(
origin: Rails.configuration.webauthn_origin,
name: "WebAuthn Rails Demo App"
)
end
end
46 changes: 23 additions & 23 deletions app/controllers/credentials_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class CredentialsController < ApplicationController
def create
create_options = relying_party.options_for_registration(
create_options = WebAuthn::Credential.options_for_create(
user: {
id: current_user.webauthn_id,
name: current_user.username,
Expand All @@ -19,29 +19,29 @@ def create
end

def callback
webauthn_credential = relying_party.verify_registration(
params,
session[:current_registration]["challenge"],
user_verification: true,
)

credential = current_user.credentials.find_or_initialize_by(
external_id: Base64.strict_encode64(webauthn_credential.raw_id)
)

if credential.update(
nickname: params[:credential_nickname],
public_key: webauthn_credential.public_key,
sign_count: webauthn_credential.sign_count
)
render json: { status: "ok" }, status: :ok
else
render json: "Couldn't add your Security Key", status: :unprocessable_entity
webauthn_credential = WebAuthn::Credential.from_create(params)

begin
webauthn_credential.verify(session[:current_registration]["challenge"], user_verification: true)

credential = current_user.credentials.find_or_initialize_by(
external_id: Base64.strict_encode64(webauthn_credential.raw_id)
)

if credential.update(
nickname: params[:credential_nickname],
public_key: webauthn_credential.public_key,
sign_count: webauthn_credential.sign_count
)
render json: { status: "ok" }, status: :ok
else
render json: "Couldn't add your Security Key", status: :unprocessable_entity
end
rescue WebAuthn::Error => e
render json: "Verification failed: #{e.message}", status: :unprocessable_entity
ensure
session.delete(:current_registration)
end
rescue WebAuthn::Error => e
render json: "Verification failed: #{e.message}", status: :unprocessable_entity
ensure
session.delete(:current_registration)
end

def destroy
Expand Down
10 changes: 4 additions & 6 deletions app/controllers/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def new
def create
user = User.new(username: params[:registration][:username])

create_options = relying_party.options_for_registration(
create_options = WebAuthn::Credential.options_for_create(
user: {
name: params[:registration][:username],
id: user.webauthn_id
Expand All @@ -29,14 +29,12 @@ def create
end

def callback
webauthn_credential = WebAuthn::Credential.from_create(params)

user = User.create!(session[:current_registration]["user_attributes"])

begin
webauthn_credential = relying_party.verify_registration(
params,
session[:current_registration]["challenge"],
user_verification: true,
)
webauthn_credential.verify(session[:current_registration]["challenge"], user_verification: true)

credential = user.credentials.build(
external_id: Base64.strict_encode64(webauthn_credential.raw_id),
Expand Down
17 changes: 10 additions & 7 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def create
user = User.find_by(username: session_params[:username])

if user
get_options = relying_party.options_for_authentication(
get_options = WebAuthn::Credential.options_for_get(
allow: user.credentials.pluck(:external_id),
user_verification: "required"
)
Expand All @@ -26,19 +26,22 @@ def create
end

def callback
webauthn_credential = WebAuthn::Credential.from_get(params)

user = User.find_by(username: session[:current_authentication]["username"])
raise "user #{session[:current_authentication]["username"]} never initiated sign up" unless user

credential = user.credentials.find_by(external_id: Base64.strict_encode64(webauthn_credential.raw_id))

begin
verified_webauthn_credential, stored_credential = relying_party.verify_authentication(
params,
webauthn_credential.verify(
session[:current_authentication]["challenge"],
public_key: credential.public_key,
sign_count: credential.sign_count,
user_verification: true,
) do |webauthn_credential|
user.credentials.find_by(external_id: Base64.strict_encode64(webauthn_credential.raw_id))
end
)

stored_credential.update!(sign_count: verified_webauthn_credential.sign_count)
credential.update!(sign_count: webauthn_credential.sign_count)
sign_in(user)

render json: { status: "ok" }, status: :ok
Expand Down
6 changes: 6 additions & 0 deletions config/initializers/webauthn.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

WebAuthn.configure do |config|
config.origin = Rails.configuration.webauthn_origin
config.rp_name = "WebAuthn Rails Demo App"
end

0 comments on commit 9f00511

Please sign in to comment.