doorkeeper-openid_connect 1.7.0 → 1.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -2
- data/README.md +40 -0
- data/app/controllers/doorkeeper/authorizations_controller.rb +17 -0
- data/app/controllers/doorkeeper/openid_connect/discovery_controller.rb +48 -26
- data/app/controllers/doorkeeper/openid_connect/userinfo_controller.rb +5 -1
- data/config/locales/en.yml +1 -0
- data/lib/doorkeeper/oauth/id_token_request.rb +8 -12
- data/lib/doorkeeper/oauth/id_token_response.rb +2 -0
- data/lib/doorkeeper/oauth/id_token_token_request.rb +2 -0
- data/lib/doorkeeper/oauth/id_token_token_response.rb +2 -0
- data/lib/doorkeeper/openid_connect.rb +26 -1
- data/lib/doorkeeper/openid_connect/claims/aggregated_claim.rb +2 -0
- data/lib/doorkeeper/openid_connect/claims/claim.rb +6 -4
- data/lib/doorkeeper/openid_connect/claims/distributed_claim.rb +2 -0
- data/lib/doorkeeper/openid_connect/claims/normal_claim.rb +2 -0
- data/lib/doorkeeper/openid_connect/claims_builder.rb +3 -1
- data/lib/doorkeeper/openid_connect/config.rb +24 -10
- data/lib/doorkeeper/openid_connect/engine.rb +2 -0
- data/lib/doorkeeper/openid_connect/errors.rb +2 -1
- data/lib/doorkeeper/openid_connect/helpers/controller.rb +45 -29
- data/lib/doorkeeper/openid_connect/id_token.rb +4 -2
- data/lib/doorkeeper/openid_connect/id_token_token.rb +2 -0
- data/lib/doorkeeper/openid_connect/oauth/authorization/code.rb +25 -8
- data/lib/doorkeeper/openid_connect/oauth/authorization_code_request.rb +4 -2
- data/lib/doorkeeper/openid_connect/oauth/password_access_token_request.rb +3 -1
- data/lib/doorkeeper/openid_connect/oauth/pre_authorization.rb +24 -3
- data/lib/doorkeeper/openid_connect/oauth/token_response.rb +3 -1
- data/lib/doorkeeper/openid_connect/orm/active_record.rb +2 -0
- data/lib/doorkeeper/openid_connect/orm/active_record/access_grant.rb +3 -1
- data/lib/doorkeeper/openid_connect/orm/active_record/request.rb +5 -3
- data/lib/doorkeeper/openid_connect/rails/routes.rb +3 -1
- data/lib/doorkeeper/openid_connect/rails/routes/mapper.rb +2 -0
- data/lib/doorkeeper/openid_connect/rails/routes/mapping.rb +2 -0
- data/lib/doorkeeper/openid_connect/response_mode.rb +30 -0
- data/lib/doorkeeper/openid_connect/response_types_config.rb +2 -2
- data/lib/doorkeeper/openid_connect/user_info.rb +2 -0
- data/lib/doorkeeper/openid_connect/version.rb +3 -1
- data/lib/doorkeeper/request/id_token.rb +2 -0
- data/lib/doorkeeper/request/id_token_token.rb +2 -0
- data/lib/generators/doorkeeper/openid_connect/install_generator.rb +4 -2
- data/lib/generators/doorkeeper/openid_connect/migration_generator.rb +3 -1
- data/lib/generators/doorkeeper/openid_connect/templates/initializer.rb +19 -5
- data/lib/generators/doorkeeper/openid_connect/templates/migration.rb.erb +3 -2
- metadata +35 -36
- data/.gitignore +0 -8
- data/.ruby-version +0 -1
- data/.travis.yml +0 -27
- data/CONTRIBUTING.md +0 -45
- data/Gemfile +0 -8
- data/Rakefile +0 -24
- data/bin/console +0 -9
- data/bin/setup +0 -8
- data/doorkeeper-openid_connect.gemspec +0 -32
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
def self.configure(&block)
|
4
6
|
if Doorkeeper.configuration.orm != :active_record
|
5
|
-
|
7
|
+
raise Errors::InvalidConfiguration, 'Doorkeeper OpenID Connect currently only supports the ActiveRecord ORM adapter'
|
6
8
|
end
|
7
9
|
|
8
10
|
@config = Config::Builder.new(&block).build
|
9
11
|
end
|
10
12
|
|
11
13
|
def self.configuration
|
12
|
-
@config || (
|
14
|
+
@config || (raise Errors::MissingConfiguration)
|
13
15
|
end
|
14
16
|
|
15
17
|
class Config
|
@@ -23,12 +25,12 @@ module Doorkeeper
|
|
23
25
|
@config
|
24
26
|
end
|
25
27
|
|
26
|
-
def jws_public_key(*
|
27
|
-
puts
|
28
|
+
def jws_public_key(*_args)
|
29
|
+
puts 'DEPRECATION WARNING: `jws_public_key` is not needed anymore and will be removed in a future version, please remove it from config/initializers/doorkeeper_openid_connect.rb'
|
28
30
|
end
|
29
31
|
|
30
32
|
def jws_private_key(*args)
|
31
|
-
puts
|
33
|
+
puts 'DEPRECATION WARNING: `jws_private_key` has been replaced by `signing_key` and will be removed in a future version, please remove it from config/initializers/doorkeeper_openid_connect.rb'
|
32
34
|
signing_key(*args)
|
33
35
|
end
|
34
36
|
end
|
@@ -71,7 +73,7 @@ module Doorkeeper
|
|
71
73
|
value = if attribute_builder
|
72
74
|
attribute_builder.new(&block).build
|
73
75
|
else
|
74
|
-
block
|
76
|
+
block || args.first
|
75
77
|
end
|
76
78
|
|
77
79
|
@config.instance_variable_set(:"@#{attribute}", value)
|
@@ -102,19 +104,23 @@ module Doorkeeper
|
|
102
104
|
option :subject_types_supported, default: [:public]
|
103
105
|
|
104
106
|
option :resource_owner_from_access_token, default: lambda { |*_|
|
105
|
-
|
107
|
+
raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.resource_owner_from_access_token_not_configured')
|
106
108
|
}
|
107
109
|
|
108
110
|
option :auth_time_from_resource_owner, default: lambda { |*_|
|
109
|
-
|
111
|
+
raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.auth_time_from_resource_owner_not_configured')
|
110
112
|
}
|
111
113
|
|
112
114
|
option :reauthenticate_resource_owner, default: lambda { |*_|
|
113
|
-
|
115
|
+
raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.reauthenticate_resource_owner_not_configured')
|
116
|
+
}
|
117
|
+
|
118
|
+
option :select_account_for_resource_owner, default: lambda { |*_|
|
119
|
+
raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.select_account_for_resource_owner_not_configured')
|
114
120
|
}
|
115
121
|
|
116
122
|
option :subject, default: lambda { |*_|
|
117
|
-
|
123
|
+
raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.subject_not_configured')
|
118
124
|
}
|
119
125
|
|
120
126
|
option :expiration, default: 120
|
@@ -124,6 +130,14 @@ module Doorkeeper
|
|
124
130
|
option :protocol, default: lambda { |*_|
|
125
131
|
::Rails.env.production? ? :https : :http
|
126
132
|
}
|
133
|
+
|
134
|
+
option :end_session_endpoint, default: lambda { |*_|
|
135
|
+
nil
|
136
|
+
}
|
137
|
+
|
138
|
+
option :discovery_url_options, default: lambda { |*_|
|
139
|
+
{}
|
140
|
+
}
|
127
141
|
end
|
128
142
|
end
|
129
143
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module Errors
|
@@ -24,7 +26,6 @@ module Doorkeeper
|
|
24
26
|
class LoginRequired < OpenidConnectError; end
|
25
27
|
class ConsentRequired < OpenidConnectError; end
|
26
28
|
class InteractionRequired < OpenidConnectError; end
|
27
|
-
class AccountSelectionRequired < OpenidConnectError; end
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
@@ -1,9 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module Helpers
|
4
6
|
module Controller
|
5
7
|
private
|
6
8
|
|
9
|
+
# FIXME: remove after Doorkeeper will merge it
|
10
|
+
def current_resource_owner
|
11
|
+
return @current_resource_owner if defined?(@current_resource_owner)
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
7
16
|
def authenticate_resource_owner!
|
8
17
|
super.tap do |owner|
|
9
18
|
next unless oidc_authorization_request?
|
@@ -11,15 +20,14 @@ module Doorkeeper
|
|
11
20
|
handle_oidc_prompt_param!(owner)
|
12
21
|
handle_oidc_max_age_param!(owner)
|
13
22
|
end
|
14
|
-
rescue Errors::OpenidConnectError =>
|
15
|
-
handle_oidc_error!(
|
23
|
+
rescue Errors::OpenidConnectError => e
|
24
|
+
handle_oidc_error!(e)
|
16
25
|
end
|
17
26
|
|
18
27
|
def oidc_authorization_request?
|
19
28
|
controller_path == Doorkeeper::Rails::Routes.mapping[:authorizations][:controllers] &&
|
20
29
|
action_name == 'new' &&
|
21
30
|
pre_auth.valid? &&
|
22
|
-
pre_auth.client &&
|
23
31
|
pre_auth.scopes.include?('openid')
|
24
32
|
end
|
25
33
|
|
@@ -31,17 +39,19 @@ module Doorkeeper
|
|
31
39
|
@_response_body = nil
|
32
40
|
|
33
41
|
error_response = if exception.type == :invalid_request
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
::Doorkeeper::OAuth::InvalidRequestResponse.new(
|
43
|
+
name: exception.type,
|
44
|
+
state: params[:state],
|
45
|
+
redirect_uri: params[:redirect_uri],
|
46
|
+
response_on_fragment: pre_auth.response_on_fragment?,
|
47
|
+
)
|
48
|
+
else
|
49
|
+
::Doorkeeper::OAuth::ErrorResponse.new(
|
50
|
+
name: exception.type,
|
51
|
+
state: params[:state],
|
52
|
+
redirect_uri: params[:redirect_uri],
|
53
|
+
response_on_fragment: pre_auth.response_on_fragment?,
|
54
|
+
)
|
45
55
|
end
|
46
56
|
|
47
57
|
response.headers.merge!(error_response.headers)
|
@@ -59,16 +69,15 @@ module Doorkeeper
|
|
59
69
|
prompt_values.each do |prompt|
|
60
70
|
case prompt
|
61
71
|
when 'none'
|
62
|
-
raise Errors::InvalidRequest if (prompt_values - [
|
72
|
+
raise Errors::InvalidRequest if (prompt_values - ['none']).any?
|
63
73
|
raise Errors::LoginRequired unless owner
|
64
|
-
raise Errors::ConsentRequired if oidc_consent_required?
|
74
|
+
raise Errors::ConsentRequired if oidc_consent_required?
|
65
75
|
when 'login'
|
66
76
|
reauthenticate_oidc_resource_owner(owner) if owner
|
67
77
|
when 'consent'
|
68
78
|
render :new
|
69
79
|
when 'select_account'
|
70
|
-
|
71
|
-
raise Errors::AccountSelectionRequired
|
80
|
+
select_account_for_oidc_resource_owner(owner)
|
72
81
|
else
|
73
82
|
raise Errors::InvalidRequest
|
74
83
|
end
|
@@ -89,36 +98,43 @@ module Doorkeeper
|
|
89
98
|
end
|
90
99
|
end
|
91
100
|
|
92
|
-
def
|
101
|
+
def return_without_oidc_prompt_param(prompt_value)
|
93
102
|
return_to = URI.parse(request.path)
|
94
103
|
return_to.query = request.query_parameters.tap do |params|
|
95
|
-
params['prompt'] = params['prompt'].to_s.sub(/\
|
104
|
+
params['prompt'] = params['prompt'].to_s.sub(/\b#{prompt_value}\s*\b/, '').strip
|
96
105
|
params.delete('prompt') if params['prompt'].blank?
|
97
106
|
end.to_query
|
107
|
+
return_to.to_s
|
108
|
+
end
|
109
|
+
|
110
|
+
def reauthenticate_oidc_resource_owner(owner)
|
111
|
+
return_to = return_without_oidc_prompt_param('login')
|
98
112
|
|
99
113
|
instance_exec(
|
100
114
|
owner,
|
101
|
-
return_to
|
115
|
+
return_to,
|
102
116
|
&Doorkeeper::OpenidConnect.configuration.reauthenticate_resource_owner
|
103
117
|
)
|
104
118
|
|
105
119
|
raise Errors::LoginRequired unless performed?
|
106
120
|
end
|
107
121
|
|
108
|
-
def
|
109
|
-
|
110
|
-
Doorkeeper::AccessToken.scopes_match?(token.scopes, pre_auth.scopes, pre_auth.client.scopes)
|
111
|
-
end
|
122
|
+
def oidc_consent_required?
|
123
|
+
!skip_authorization? && !matching_token?
|
112
124
|
end
|
113
125
|
|
114
|
-
def
|
115
|
-
|
126
|
+
def select_account_for_oidc_resource_owner(owner)
|
127
|
+
return_to = return_without_oidc_prompt_param('select_account')
|
116
128
|
|
117
|
-
|
129
|
+
instance_exec(
|
130
|
+
owner,
|
131
|
+
return_to,
|
132
|
+
&Doorkeeper::OpenidConnect.configuration.select_account_for_resource_owner
|
133
|
+
)
|
118
134
|
end
|
119
135
|
end
|
120
136
|
end
|
121
137
|
end
|
122
138
|
|
123
|
-
Helpers::Controller.
|
139
|
+
Helpers::Controller.prepend OpenidConnect::Helpers::Controller
|
124
140
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
class IdToken
|
@@ -9,7 +11,7 @@ module Doorkeeper
|
|
9
11
|
@access_token = access_token
|
10
12
|
@nonce = nonce
|
11
13
|
@resource_owner = Doorkeeper::OpenidConnect.configuration.resource_owner_from_access_token.call(access_token)
|
12
|
-
@issued_at = Time.now
|
14
|
+
@issued_at = Time.zone.now
|
13
15
|
end
|
14
16
|
|
15
17
|
def claims
|
@@ -46,7 +48,7 @@ module Doorkeeper
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def audience
|
49
|
-
@access_token.application.uid
|
51
|
+
@access_token.application.try(:uid)
|
50
52
|
end
|
51
53
|
|
52
54
|
def expiration
|
@@ -1,22 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module OAuth
|
4
6
|
module Authorization
|
5
7
|
module Code
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
if Doorkeeper::OAuth::Authorization::Code.method_defined?(:issue_token!)
|
9
|
+
def issue_token!
|
10
|
+
super.tap do |access_grant|
|
11
|
+
create_openid_request(access_grant) if pre_auth.nonce.present?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
alias issue_token issue_token!
|
16
|
+
else
|
17
|
+
# FIXME: drop this after dropping support of Doorkeeper < 5.4
|
18
|
+
def issue_token
|
19
|
+
super.tap do |access_grant|
|
20
|
+
create_openid_request(access_grant) if pre_auth.nonce.present?
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def create_openid_request(access_grant)
|
28
|
+
::Doorkeeper::OpenidConnect::Request.create!(
|
29
|
+
access_grant: access_grant,
|
30
|
+
nonce: pre_auth.nonce
|
31
|
+
)
|
32
|
+
end
|
16
33
|
end
|
17
34
|
end
|
18
35
|
end
|
19
36
|
end
|
20
37
|
|
21
|
-
OAuth::Authorization::Code.
|
38
|
+
OAuth::Authorization::Code.prepend OpenidConnect::OAuth::Authorization::Code
|
22
39
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module OAuth
|
@@ -8,7 +10,7 @@ module Doorkeeper
|
|
8
10
|
super
|
9
11
|
|
10
12
|
nonce =
|
11
|
-
if openid_request = grant.openid_request
|
13
|
+
if (openid_request = grant.openid_request)
|
12
14
|
openid_request.destroy!
|
13
15
|
openid_request.nonce
|
14
16
|
end
|
@@ -20,5 +22,5 @@ module Doorkeeper
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
OAuth::AuthorizationCodeRequest.
|
25
|
+
OAuth::AuthorizationCodeRequest.prepend OpenidConnect::OAuth::AuthorizationCodeRequest
|
24
26
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module OAuth
|
@@ -20,5 +22,5 @@ module Doorkeeper
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
OAuth::PasswordAccessTokenRequest.
|
25
|
+
OAuth::PasswordAccessTokenRequest.prepend OpenidConnect::OAuth::PasswordAccessTokenRequest
|
24
26
|
end
|
@@ -1,16 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module OAuth
|
4
6
|
module PreAuthorization
|
5
7
|
attr_reader :nonce
|
6
8
|
|
7
|
-
def initialize(server, attrs = {})
|
8
|
-
|
9
|
+
def initialize(server, attrs = {}, resource_owner = nil)
|
10
|
+
if (Doorkeeper::VERSION::MAJOR >= 5 && Doorkeeper::VERSION::MINOR >= 4) ||
|
11
|
+
Doorkeeper::VERSION::MAJOR >= 6
|
12
|
+
super
|
13
|
+
else
|
14
|
+
super(server, attrs)
|
15
|
+
end
|
9
16
|
@nonce = attrs[:nonce]
|
10
17
|
end
|
18
|
+
|
19
|
+
# This method will be updated when doorkeeper move to version > 5.2.2
|
20
|
+
# TODO: delete this method and refactor response_on_fragment? method (below) when doorkeeper gem version constrains is > 5.2.2
|
21
|
+
def error_response
|
22
|
+
if error == :invalid_request
|
23
|
+
Doorkeeper::OAuth::InvalidRequestResponse.from_request(self, response_on_fragment: response_on_fragment?)
|
24
|
+
else
|
25
|
+
Doorkeeper::OAuth::ErrorResponse.from_request(self, response_on_fragment: response_on_fragment?)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def response_on_fragment?
|
30
|
+
Doorkeeper::OpenidConnect::ResponseMode.new(response_type).fragment?
|
31
|
+
end
|
11
32
|
end
|
12
33
|
end
|
13
34
|
end
|
14
35
|
|
15
|
-
OAuth::PreAuthorization.
|
36
|
+
OAuth::PreAuthorization.prepend OpenidConnect::OAuth::PreAuthorization
|
16
37
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module OAuth
|
@@ -19,5 +21,5 @@ module Doorkeeper
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
OAuth::TokenResponse.
|
24
|
+
OAuth::TokenResponse.prepend OpenidConnect::OAuth::TokenResponse
|
23
25
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module AccessGrant
|
@@ -12,5 +14,5 @@ module Doorkeeper
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
|
-
AccessGrant.
|
17
|
+
AccessGrant.prepend OpenidConnect::AccessGrant
|
16
18
|
end
|