Description
I've build an OAuth2 provider using the doorkeeper engine with devise. On my client app I'm using a custom omniauth-oauth2 -v 1.3.1 strategy. Everything works well, but after I sign in if I hit the back button on the browser I get
I dug into the omniauth-oath2 code and it appears that there are two methods that I think are closely related to this problem, one that creates the session["omniauth.state"] from the url params:
def authorize_params
options.authorize_params[:state] = SecureRandom.hex(24)
params = options.authorize_params.merge(options_for("authorize"))
if OmniAuth.config.test_mode
@env ||= {}
@env["rack.session"] ||= {}
end
session["omniauth.state"] = params[:state]
params
end
and one that checks this and deletes this from the session on the callback process:
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"]))
elsif !options.provider_ignores_state && (request.params["state"].to_s.empty? || request.params["state"] != session.delete("omniauth.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?
super
end
rescue ::OAuth2::Error, CallbackError => e
fail!(:invalid_credentials, e)
rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
fail!(:timeout, e)
rescue ::SocketError => e
fail!(:failed_to_connect, e)
end
It appears that somehow the first method is not called on going back from the browser. Does someone had the same problem and is there a solution to this problem without setting the :provider_ignores_state
to true
. Do I need to set something on the provider, I really don't get it, plus I can't seem to find this problem anywhere on the web and I highly doubt it I'm the first one that recognizes it, but I may be the first one that can't find a reasonable solution without affecting security.