Skip to content

Issue with random state parameter in OmniAuth Okta #36

@piligarcia

Description

@piligarcia

Description:

When using the Okta gem for OmniAuth OAuth integration, I encountered an issue where the state parameter sent in the initial authorization request was overridden by a random state generated by the gem. This happened because the omniauth-oauth2 gem, which the Okta gem relies on, has a method in lib/omniauth/strategies/oauth2.rb that sets state to a random value:

def authorize_params # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  options.authorize_params[:state] = SecureRandom.hex(24)

  ....
end

As a result, the callback returned a different state than what I originally sent, which broke functionality that relied on the exact value of state. The state parameter is essential for maintaining the integrity of the request, ensuring CSRF protection, and properly handling OAuth callbacks.

Solution:

I found a workaround by creating an initializer to override the authorize_params method and ensure the state is returned as it was originally sent:

class OmniAuth::Strategies::Okta < OmniAuth::Strategies::OAuth2
  option :authorize_options, %i[scope state]

  def authorize_params
    super.tap do |params|
      options[:authorize_options].each do |k|
        params[k] = request.params[k.to_s] if request.params[k.to_s].present?
      end

      session["omniauth.state"] = params[:state] if params[:state].present?
    end
  end
end

Additionally, this approach allows other parameters to be passed by adding them to authorize_options.

Key points:

  • Including scope in authorize_options is necessary to avoid returning nil values.
  • Storing the state in the session with session["omniauth.state"] = params[:state] is required to prevent CSRF errors.
  • This solution also allows you to pass other parameters, such as login_hint, by adding them to authorize_options, enhancing the flexibility of your OAuth flow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions