From 87d2de0b424669161b4c0113f416e5eca236e1a3 Mon Sep 17 00:00:00 2001 From: Lud Date: Thu, 27 Mar 2025 13:35:23 +0100 Subject: [PATCH 1/4] wip Co-Authored-By: Mohammed Abdulkareem <18808136+mohammed-io@users.noreply.github.com> --- lib/omniauth/strategies/apple.rb | 33 ++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/omniauth/strategies/apple.rb b/lib/omniauth/strategies/apple.rb index 347afc2..134e0cb 100644 --- a/lib/omniauth/strategies/apple.rb +++ b/lib/omniauth/strategies/apple.rb @@ -20,6 +20,8 @@ class Apple < OmniAuth::Strategies::OAuth2 scope: 'email name' option :authorized_client_ids, [] + option :nonce, :session # :session, :local, or :ignore + uid { id_info[:sub] } # Documentation on parameters @@ -70,11 +72,34 @@ def authorized_client_ids end def new_nonce - session['omniauth.nonce'] = SecureRandom.urlsafe_base64(16) + nonce = SecureRandom.urlsafe_base64(16) + case options.nonce + when :session + session['omniauth.nonce'] = nonce + end + nonce end def stored_nonce - session.delete('omniauth.nonce') + case options.nonce + when :session + session.delete('omniauth.nonce') + when :param + request.params['nonce'] + end + end + + def verify_nonce!(id_token) + case options.nonce + when :session + invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce + when :param + invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce + when :ignore + true + else + raise ArgumentError, "Invalid nonce option: #{options.nonce}. Must be :session, :param, or :ignore" + end end def id_info @@ -128,10 +153,6 @@ def verify_exp!(id_token) invalid_claim! :exp unless id_token[:exp] >= Time.now.to_i end - def verify_nonce!(id_token) - invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce - end - def invalid_claim!(claim) raise CallbackError.new(:id_token_claims_invalid, "#{claim} invalid") end From 32d4352eeb3e0a0afd7ab2a9264d9b214cb9796a Mon Sep 17 00:00:00 2001 From: Lud Date: Thu, 27 Mar 2025 13:47:10 +0100 Subject: [PATCH 2/4] fix comment Co-Authored-By: Mohammed Abdulkareem <18808136+mohammed-io@users.noreply.github.com> --- lib/omniauth/strategies/apple.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth/strategies/apple.rb b/lib/omniauth/strategies/apple.rb index 134e0cb..bd0829b 100644 --- a/lib/omniauth/strategies/apple.rb +++ b/lib/omniauth/strategies/apple.rb @@ -20,7 +20,7 @@ class Apple < OmniAuth::Strategies::OAuth2 scope: 'email name' option :authorized_client_ids, [] - option :nonce, :session # :session, :local, or :ignore + option :nonce, :session # :session, :param, or :ignore uid { id_info[:sub] } From 529909243c41f1f6bd22baf6ffb98a838f834060 Mon Sep 17 00:00:00 2001 From: Lud Date: Thu, 27 Mar 2025 13:50:24 +0100 Subject: [PATCH 3/4] document nonce Co-Authored-By: Mohammed Abdulkareem <18808136+mohammed-io@users.noreply.github.com> --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0905e18..2961313 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,8 @@ Rails.application.config.middleware.use OmniAuth::Builder do scope: 'email name', team_id: ENV['TEAM_ID'], key_id: ENV['KEY_ID'], - pem: ENV['PRIVATE_KEY'] + pem: ENV['PRIVATE_KEY'], + nonce: :session # :session, :param, or :ignore. Set this to ":param" in an API only backend } end ``` From b14114a658cefd5eb909142f65b1d19921e2b798 Mon Sep 17 00:00:00 2001 From: Lud Date: Thu, 27 Mar 2025 13:52:57 +0100 Subject: [PATCH 4/4] simplify Co-Authored-By: Mohammed Abdulkareem <18808136+mohammed-io@users.noreply.github.com> --- lib/omniauth/strategies/apple.rb | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/omniauth/strategies/apple.rb b/lib/omniauth/strategies/apple.rb index bd0829b..96ea1e1 100644 --- a/lib/omniauth/strategies/apple.rb +++ b/lib/omniauth/strategies/apple.rb @@ -90,16 +90,10 @@ def stored_nonce end def verify_nonce!(id_token) - case options.nonce - when :session - invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce - when :param - invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce - when :ignore - true - else - raise ArgumentError, "Invalid nonce option: #{options.nonce}. Must be :session, :param, or :ignore" - end + return true if options.nonce == :ignore + raise ArgumentError, "Invalid nonce option: #{options.nonce}. Must be :session, :param, or :ignore" unless [:session, :param].include?(options.nonce) + + invalid_claim! :nonce unless id_token[:nonce] && id_token[:nonce] == stored_nonce end def id_info