-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Migration from old versions
The intent of this document is to make migration of breaking changes as easy as possible. Please note that all breaking changes may not be included here. Please check the CHANGELOG.md for a full list of changes before finalizing the upgrade process.
Follow latest changes (specially backwards incompatible ones, we follow semantic versioning) in the CHANGELOG: https://github.com/doorkeeper-gem/doorkeeper/blob/main/CHANGELOG.md.
-
Starting from Doorkeeper 5.5 client authentication for Resource Owner Password Grant is required as stated in OAuth RFC.
[IMPORTANT] you need to create a new OAuth client (Doorkeeper::Application) if you didn't have it before and use client credentials in HTTP Basic auth if you previously used this grant flow without client authentication. For migration purposes you could enable skip_client_authentication_for_password_grant configuration option to true, but such behavior (as well as configuration option) would be completely removed in a future version of Doorkeeper. All the users of your provider application now need to include client credentials when they use this grant flow.
-
Token revocation endpoint now requires strict client authentication as required by the RFC 7009. So clients need to send
client_id
(in case of public clients) andclient_id
&client_secret
(for private clients).Please take a look at section 2.1. Revocation Request of the RFC7009 and then section 2.3. Client Authentication of RFC6749 with section 5. Security Considerations of RFC7009 to get more info on how you could implement authentication (via HTTP Auth header or via params which is not recommended).
-
Doorkeeper now supports polymorphic resource owners (if configured), so internals were changes to pass
resource owner
instance across the methods and objects, not just it's ID. So if you have some patches for Doorkeeper internals - you need to change them. See #1355 for details. -
Doorkeeper built-in Application views not strictly set
as
option equal todoorkeeper_application
forform_for
. If you previously changed it on your custom views or overridden controller - make sure you didn't break something.
- Return error message properly, add descriptive
error_description
forinvalid_request
error:
# invalid_request error message
# config/locales/en.yml
invalid_request:
unknown: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
missing_param: 'Missing required parameter: %{value}.'
not_support_pkce: 'Invalid code_verifier parameter. Server does not support pkce.'
request_not_authorized: 'Request need to be authorized. Required parameter for authorizing request is missing or invalid.'
- As RFC6749#section-3.3,
scope
param need to be provided at authorization request in case server doesn't defineddefault_scope
--> Change column attribute:scopes
ofoauth_access_grants
(table that saving authorization_code) MUST NOT be null. See https://stackoverflow.com/a/58714209/10780636 for details - Change made at:
lib/generators/doorkeeper/templates/migration.rb.erb
Of theoauth_access_grants
table, changescopes
to null: false, default: ''
-
native_redirect_uri
option is deprecated now and will be removed soon (see more details here #1238).
- Error responses now return a 400 HTTP status by default (previously 401), and a 401 only for
invalid_client
andinvalid_token
errors. - Those who defined
custom_access_token_expires_in
configuration option need to check their block implementation: if you are callingoauth_client.application
to getDoorkeeper::Application
instance of your client application, then you need to replace it with justoauth_client
. -
[IMPORTANT]: Doorkeeper access token value, client secrets and so on now has more complexity. It may have possible side-effects in case you have custom database constraints for access token value / application secrets / refresh tokens or you patched Doorkeeper models and introduced token value validations, or you are using database with case-insensitive
WHERE
clause like MySQL (in this case you can face some collisions). Doorkeeper < 5.1.x access token value matched[a-f0-9]
regex, and now it matches[a-zA-Z0-9\-_]
. In case you have some db restrictions and you don't use custom token generator please change configuration optiondefault_generator_method
inconfig/initializers/doorkeeper.rb
to:hex
.
-
Doorkeeper::Application
now has a new boolean column namedconfidential
that istrue
by default and hasNOT NULL CONSTRAINT
. This column is required to allow creating Public & Private Clients as mentioned in Section 8.5 of draft-ietf-oauth-native-apps-12 of OAuth 2 RFC which was previously unavailable. If you are migrating from the Doorkeeper <= 5.0, then you can easily add this column by generating a proper migration file using the following command:rails generate doorkeeper:confidential_applications
.[IMPORTANT]: all the applications (clients) starting from 5.0 / 4.4.x releases are considered as private by default. You need to manually change
confidential
column tofalse
if you are using public clients, otherwise your mobile or other applications will not be able to authorize. See #1142 for more details.
-
[IMPORTANT]: Doorkeeper JSON responses changed:
scopes
field was replaced withscope
,expires_in_seconds
toexpires_in
to be consistent and match the RFC. -
Doorkeeper#configured?
,Doorkeeper#database_installed?
, andDoorkeeper#installed?
methods were removed, so any Doorkeeper ORM extension doesn't need to support these methods starting from 5.0. - Many memoized and other instance variables (like
@token
indoorkeeper_token
method forDoorkeeper::Helpers::Controller
) were renamed during refactoring, so if you are using them — just don't do it and call the original methods (helpers, etc) in order to get the required value. - Test suite now has a refactored infrastructure:
spec_helper_integration
now renamed to industry-standardspec_helper
. -
custom_access_token_expires_in
option now provides aDoorkeeper::OAuth::Authorization::Context
object (|context|
) instead of raw params (|client, grant_type, scopes|
). The context object has all these variables and you can access them in the block (likecontext.grant_type
orcontext.client
). -
admin_authenticator
block now returns "403 Forbidden" response by default if developer didn't declare another behavior explicitly. - Previously authorization code response route was
/oauth/authorize/<code>
, now it isoauth/authorize/native?code=<code>
(in order to help applications to automatically find the code value).
- Bootstrap CSS was updated from 3.x to 4.0.
-
[IMPORTANT]: 4.4.x release includes backport security fix from 5.x for token revocation when using public clients, so starting from this version all the applications (clients) are considered as private by default. You need to manually change
confidential
column tofalse
if you are using public clients, otherwise your mobile (or other) applications will not be able to authorize. See #1142 for more details.
- FactoryGirl changed to FactoryBot.
- Previously authorization code response route was
/oauth/authorize/<code>
, now it isoauth/authorize/native?code=<code>
(in order to help applications to automatically find the code value).
- MongoDB adapter extracted to its own extension.
-
doorkeeper_unauthorized_render_options(error:)
anddoorkeeper_forbidden_render_options(error:)
now accepterror
keyword argument.
- Added
scopes
column to applications. Add it withrails generate doorkeeper:application_scopes
generator.
-
doorkeeper_for
DSL was changed tobefore_action :dorkeeper_authorize!
. -
test_redirect_uri
option renamed tonative_redirect_uri
. -
mount Doorkeeper::Engine
now replaced withuse_doorkeeper
routes helper.
Doorkeeper is not an isolated engine anymore. Which means that most of the paths and old related engine methods won't work. Here's a list of things that changed:
-
mount Doorkeeper::Engine
won't work. Replace it withuse_doorkeeper
in yourconfig/routes.rb
file. - All route paths have changed. If you generated all views, or use custom ones, you'll have to prepend
oauth_
to each of them:
# also applies to prefixes (edit_ and new_)
authorized_applications(_path|_url) => oauth_authorized_applications(_path|_url)
applications(_path|_url) => oauth_applications(_path|_url)
authorization(_path|_url) => oauth_authorization(_path|_url)
- The locale file has been updated. You'll need to reinstall the file with
rails g doorkeeper:install
(ignore other existing files) to ensure the gem works properly. - Authorization code is now configurable:
authorization_code_expires_in 10.minutes
The column resource_owner_id
accepts null values, since we now support the Client Credentials flow.
change_column :oauth_access_tokens, :resource_owner_id, :integer, :null => true
Two things were changed in scopes
- The configuration for scopes has changed. You now have to use
default_scopes
andoptional_scopes
instead of theauthorization_scopes
block:
Doorkeeper.configure do
default_scopes :public
optional_scopes :write, :update
end
- You have to translate your scopes in your application's locale file(s).
en:
doorkeeper:
scopes:
public: "Access your public data"
write: "Update your data"
Add indexes to database:
class UpgradeToVersion03 < ActiveRecord::Migration
def change
add_index :oauth_applications, :uid, :unique => true
add_index :oauth_access_grants, :token, :unique => true
add_index :oauth_access_tokens, :token, :unique => true
add_index :oauth_access_tokens, :resource_owner_id
add_index :oauth_access_tokens, :refresh_token, :unique => true
end
end
-
doorkeeper_for
does not accept the:all
option anymore. -
doorkeeper_for
only accepts:except
option when:all
was specified.
class UpgradeToVersion02 < ActiveRecord::Migration
def change
add_column :oauth_access_grants, :scopes, :string
# If you are upgrading from version 0.1.0, uncomment the line below.
# add_column :oauth_access_grants, :revoked_at, :datetime
add_column :oauth_access_tokens, :refresh_token, :string
add_column :oauth_access_tokens, :scopes, :string
add_column :oauth_access_tokens, :expires_in, :integer
remove_column :oauth_access_tokens, :expires_at
end
end