From 738ce3d09916f1a8b23f378b0d3e5182a931bb3a Mon Sep 17 00:00:00 2001 From: Pierre Pretorius Date: Wed, 1 Mar 2017 17:09:38 +0200 Subject: [PATCH 1/3] Correctly redirect back to multiple origins after sign in. --- lib/omniauth/strategies/oauth2.rb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/omniauth/strategies/oauth2.rb b/lib/omniauth/strategies/oauth2.rb index 3ffff1b..493ca9d 100644 --- a/lib/omniauth/strategies/oauth2.rb +++ b/lib/omniauth/strategies/oauth2.rb @@ -55,7 +55,11 @@ def authorize_params @env ||= {} @env["rack.session"] ||= {} end - session["omniauth.state"] = params[:state] + session["omniauth.states"] ||= [] + session["omniauth.states"] << params[:state] + + session["omniauth.state_origins"] ||= {} + session["omniauth.state_origins"][params[:state]] = session['omniauth.origin'] params end @@ -63,15 +67,19 @@ def token_params options.token_params.merge(options_for("token")) end - def callback_phase # rubocop:disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity + def callback_phase error = request.params["error_reason"] || request.params["error"] if error fail!(error, CallbackError.new(request.params["error"], request.params["error_description"] || request.params["error_reason"], request.params["error_uri"])) - elsif !options.provider_ignores_state && (request.params["state"].to_s.empty? || request.params["state"] != session.delete("omniauth.state")) + elsif !options.provider_ignores_state && (request.params["state"].to_s.empty? || session["omniauth.states"].empty? || !session["omniauth.states"].include?(request.params["state"])) fail!(:csrf_detected, CallbackError.new(:csrf_detected, "CSRF detected")) else self.access_token = build_access_token self.access_token = access_token.refresh! if access_token.expired? + + if session['omniauth.state_origins'] && session['omniauth.state_origins'][request.params['state']] + env['omniauth.origin'] = session['omniauth.state_origins'][request.params['state']] + end super end rescue ::OAuth2::Error, CallbackError => e From 24b847dbded076d354390cbb7b04b17f18426cab Mon Sep 17 00:00:00 2001 From: Pierre Pretorius Date: Wed, 1 Mar 2017 17:19:30 +0200 Subject: [PATCH 2/3] Restore rubocop comments. --- lib/omniauth/strategies/oauth2.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/omniauth/strategies/oauth2.rb b/lib/omniauth/strategies/oauth2.rb index 493ca9d..7075499 100644 --- a/lib/omniauth/strategies/oauth2.rb +++ b/lib/omniauth/strategies/oauth2.rb @@ -67,7 +67,7 @@ def token_params options.token_params.merge(options_for("token")) end - def callback_phase + def callback_phase # rubocop:disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity error = request.params["error_reason"] || request.params["error"] if error fail!(error, CallbackError.new(request.params["error"], request.params["error_description"] || request.params["error_reason"], request.params["error_uri"])) From e246fa9e7316b8f5d021332efd696200cf411423 Mon Sep 17 00:00:00 2001 From: Pierre Pretorius Date: Thu, 2 Mar 2017 08:51:56 +0200 Subject: [PATCH 3/3] Remove state and origin from session once used. --- lib/omniauth/strategies/oauth2.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/omniauth/strategies/oauth2.rb b/lib/omniauth/strategies/oauth2.rb index 7075499..11f353f 100644 --- a/lib/omniauth/strategies/oauth2.rb +++ b/lib/omniauth/strategies/oauth2.rb @@ -71,14 +71,14 @@ def callback_phase # rubocop:disable AbcSize, CyclomaticComplexity, MethodLength error = request.params["error_reason"] || request.params["error"] if error fail!(error, CallbackError.new(request.params["error"], request.params["error_description"] || request.params["error_reason"], request.params["error_uri"])) - elsif !options.provider_ignores_state && (request.params["state"].to_s.empty? || session["omniauth.states"].empty? || !session["omniauth.states"].include?(request.params["state"])) + elsif !options.provider_ignores_state && (request.params["state"].to_s.empty? || session["omniauth.states"].empty? || !session["omniauth.states"].delete(request.params["state"])) fail!(:csrf_detected, CallbackError.new(:csrf_detected, "CSRF detected")) else self.access_token = build_access_token self.access_token = access_token.refresh! if access_token.expired? if session['omniauth.state_origins'] && session['omniauth.state_origins'][request.params['state']] - env['omniauth.origin'] = session['omniauth.state_origins'][request.params['state']] + env['omniauth.origin'] = session['omniauth.state_origins'].delete(request.params['state']) end super end