ruby-on-railsdoorkeeper

Missing required parameter: scope. after doorkeeper gem upgrade from 5.1.0 to 5.2.1


After a gem upgrade of doorkeeper from 5.1.0 to 5.2.1 on the Rails (5.2.3) application that provides authorization, the login for the application requesting authorization does not work anymore. The page on the authorizing application states Missing required parameter: scope. although we do not use scopes.

There are some lines about scopes in the migration notes but they don't speak to me. https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions#database-changes

I understood that I had to create a migration like this one but the issue persisted:

# frozen_string_literal: true

class ChangeScopesOnOAuthAccessGrants < ActiveRecord::Migration[5.2]
  def up
    change_column_default :oauth_access_grants, :scopes, from: nil, to: ''
    change_column_null :oauth_access_grants, :scopes, false
  end

  def down
    change_column_default :oauth_access_grants, :scopes, from: '', to: nil
    change_column_null :oauth_access_grants, :scopes, true
  end
end

The configuration doorkeeper.rb on the authorizing application is as simple as:

Doorkeeper.configure do
  orm :active_record

  resource_owner_authenticator do
    current_admin_user || redirect_to(new_admin_user_session_path(params.permit(:client_id, :redirect_uri, :response_type, :state)))
  end

  admin_authenticator do
    current_admin_user || redirect_to(new_admin_user_session_path)
  end

  access_token_expires_in 24.hours
end

I had a deeper look into the response before and after running the migrations. Using binding.pryin the Doorkeeper module's AuthorizationsController#new (inheriting from Doorkeeper::ApplicationController), I can confirm that the instance of Doorkeeper::OAuth::PreAuthorization returns nil for the attribute scope but not for scopes.

After invoking pre_auth.authorizable?, I get this objects and these values:

#<Doorkeeper::OAuth::PreAuthorization:0x00007fad33f25390
 @client=
  #<Doorkeeper::OAuth::Client:0x00007fad364b22e8
   @application=
    #<Doorkeeper::Application:0x00007fad364b26d0
     id: 2,
     name: "...",
     uid: "...",
     secret: "..",
     redirect_uri:
      "http://localhost:3001/users/auth/doorkeeper/callback",
     scopes: "",
     created_at: Tue, 24 Oct 2017 11:56:13 CEST +02:00,
     updated_at: Thu, 03 Oct 2019 18:53:35 CEST +02:00,
     confidential: true>>,
 @client_id="...",
 @code_challenge=nil,
 @code_challenge_method=nil,
 @error=:invalid_request,
 @missing_param=:scope,
 @redirect_uri="http://localhost:3001/users/auth/doorkeeper/callback",
 @response_type="code",
 @scope=nil,
 @server=
  #<Doorkeeper::Config:0x00007fad33b72180
   @access_token_expires_in=24 hours,
   @api_only=false,
   @application_secret_strategy=Doorkeeper::SecretStoring::???,
   @authenticate_admin=#<Proc:0x00007fad33b71d20@/Users/.../config/initializers/doorkeeper.rb:11>,
   @authenticate_resource_owner=#<Proc:0x00007fad33b71eb0@/Users/.../config/initializers/doorkeeper.rb:6>,
   @default_scopes=#<Doorkeeper::OAuth::Scopes:0x00007fad364cb7c0 @scopes=[]>,
   @orm=:active_record,
   @token_secret_strategy=Doorkeeper::SecretStoring::???>,
 @state="...">

I currently don't have any leads for problem solving. Thanks for your hints!


Solution

  • I had the same issue. It seems you always need to provide a scope parameter, either in your authorization request or configure a default_scope (there is an example in config). Also, the default or requested scope must match one of your client application scopes, or you will then get The requested scope is invalid, unknown, or malformed..

    This is mentioned in Migration from old versions, but explained as a database change. The linked RFC6749#section-3.3 states the new requirement more clearly:

    If the client omits the scope parameter when requesting authorization, the authorization server MUST either process the request using a pre-defined default value or fail the request indicating an invalid scope. The authorization server SHOULD document its scope requirements and default value (if defined).

    I agree this doesn't seem adequately documented in Migration from old versions or Scopes but it seems important that they're more faithful to RFC6749. I'm using grant_type: 'authorization_code', and "scope" isn't even mentioned in Authorization Code Flow.