doorkeeper-openid_connect 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +41 -17
- data/README.md +34 -6
- data/app/controllers/doorkeeper/openid_connect/discovery_controller.rb +1 -5
- data/app/controllers/doorkeeper/openid_connect/userinfo_controller.rb +1 -1
- data/config/locales/en.yml +7 -0
- data/doorkeeper-openid_connect.gemspec +1 -1
- data/lib/doorkeeper/openid_connect/claims/claim.rb +6 -6
- data/lib/doorkeeper/openid_connect/config.rb +14 -14
- data/lib/doorkeeper/openid_connect/errors.rb +30 -0
- data/lib/doorkeeper/openid_connect/helpers/controller.rb +56 -18
- data/lib/doorkeeper/openid_connect/id_token.rb +4 -4
- data/lib/doorkeeper/openid_connect/oauth/authorization/code.rb +1 -1
- data/lib/doorkeeper/openid_connect/user_info.rb +3 -3
- data/lib/doorkeeper/openid_connect/version.rb +1 -1
- data/lib/doorkeeper/openid_connect.rb +1 -0
- data/lib/generators/doorkeeper/openid_connect/templates/initializer.rb +8 -8
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81502614dddbd89303cca3b8672ddb66b5fb040d
|
4
|
+
data.tar.gz: 26b9a1a0144782f9476c72818f74440f7b4ec2c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af7899974ca8eccfc6225039c3495ef0772920445c90e8fa3fa65b1007a2cbf29599e0e69a45070339f157a2c91f56723c119c772006556db6a5d7ca9e877cf6
|
7
|
+
data.tar.gz: 73504df5e1495586943d6f172550225fd114fc9665bb5fcc8a7da47ffd6a4a00abd3bc13625af183be1510dec00883d70412b7f8a2d1225eeb49948252922b8f
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.3
|
data/CHANGELOG.md
CHANGED
@@ -1,24 +1,48 @@
|
|
1
|
+
### Unreleased
|
2
|
+
|
3
|
+
#### Changes
|
4
|
+
|
5
|
+
<a name="v1.1.1"></a>
|
6
|
+
### v1.1.1 (2017-01-18)
|
7
|
+
|
8
|
+
#### Upgrading
|
9
|
+
|
10
|
+
- The configuration setting `jws_public_key` wasn't actually used, it's deprecated now and will be removed in the next major release
|
11
|
+
|
12
|
+
#### Features
|
13
|
+
|
14
|
+
- Claims now receive an optional second `scopes` argument which allow you to dynamically adjust claim values based on the requesting applications' scopes (by @nbibler)
|
15
|
+
- The `prompt` parameter values `login` and `consent` are now supported
|
16
|
+
- The configuration setting `protocol` was added (by @gigr)
|
17
|
+
|
18
|
+
#### Bugfixes
|
19
|
+
|
20
|
+
- Standard Claims are now mapped correctly to their default scopes (by @tylerhunt)
|
21
|
+
- Blank `nonce` parameters are now ignored
|
22
|
+
|
23
|
+
#### Changes
|
24
|
+
|
25
|
+
- `nil` values and empty strings are now removed from the UserInfo and IdToken responses
|
26
|
+
- Allow `json-jwt` dependency at ~> 1.6. (by @nbibler)
|
27
|
+
- Configuration blocks no longer internally use `instance_eval` which previously gave undocumented and unexpected `self` access to the caller (by @nbibler)
|
28
|
+
|
1
29
|
<a name="v1.1.0"></a>
|
2
30
|
### v1.1.0 (2016-11-30)
|
3
31
|
|
4
32
|
This release is a general clean-up and adds support for some advanced OpenID Connect features.
|
5
|
-
|
33
|
+
|
34
|
+
#### Upgrading
|
35
|
+
|
36
|
+
- This version adds a table to store temporary nonces, use the generator `doorkeeper:openid_connect:migration` to create a migration
|
37
|
+
- Implement the new configuration callbacks `auth_time_from_resource_owner` and `reauthenticate_resource_owner` to support advanced features
|
6
38
|
|
7
39
|
#### Features
|
8
40
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
#### Bug Fixes
|
19
|
-
|
20
|
-
* Work around response_body issue on Rails 5, fix specs ([bc4ac76](/../../commit/bc4ac76))
|
21
|
-
* Return auth_time in ID token claims ([490f756](/../../commit/490f756))
|
22
|
-
* Don't require nonce ([d2945da](/../../commit/d2945da))
|
23
|
-
* Also support POST requests to userinfo ([87a6577](/../../commit/87a6577))
|
24
|
-
* Add openid scope to Doorkeeper configuration ([8169c2d](/../../commit/8169c2d))
|
41
|
+
- Add discovery endpoint ([a16caa8](/../../commit/a16caa8))
|
42
|
+
- Add webfinger and keys endpoints for discovery ([f70898b](/../../commit/f70898b))
|
43
|
+
- Add supported claims to discovery response ([1d8f9ea](/../../commit/1d8f9ea))
|
44
|
+
- Support prompt=none parameter ([c775d8b](/../../commit/c775d8b))
|
45
|
+
- Store and return nonces in IdToken responses ([d28ca8c](/../../commit/d28ca8c))
|
46
|
+
- Add generator for initializer ([80399fd](/../../commit/80399fd))
|
47
|
+
- Support max_age parameter ([aabe3aa](/../../commit/aabe3aa))
|
48
|
+
- Respect scope grants in UserInfo response ([25f2170](/../../commit/25f2170))
|
data/README.md
CHANGED
@@ -5,7 +5,9 @@
|
|
5
5
|
[![Code Climate](https://codeclimate.com/github/doorkeeper-gem/doorkeeper-openid_connect.svg)](https://codeclimate.com/github/doorkeeper-gem/doorkeeper-openid_connect)
|
6
6
|
[![Gem Version](https://badge.fury.io/rb/doorkeeper-openid_connect.svg)](https://rubygems.org/gems/doorkeeper-openid_connect)
|
7
7
|
|
8
|
-
This library implements [OpenID Connect](http://openid.net/connect/) for Rails applications on top of the [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) OAuth 2.0 framework.
|
8
|
+
This library implements an [OpenID Connect](http://openid.net/connect/) authentication provider for Rails applications on top of the [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) OAuth 2.0 framework.
|
9
|
+
|
10
|
+
OpenID Connect is a single-sign-on and identity layer with a [growing list of server and client implementations](http://openid.net/developers/libraries/). If you're looking for a client in Ruby check out [omniauth-openid-connect](https://github.com/jjbohn/omniauth-openid-connect/).
|
9
11
|
|
10
12
|
## Table of Contents
|
11
13
|
|
@@ -16,6 +18,7 @@ This library implements [OpenID Connect](http://openid.net/connect/) for Rails a
|
|
16
18
|
- [Claims](#claims)
|
17
19
|
- [Routes](#routes)
|
18
20
|
- [Nonces](#nonces)
|
21
|
+
- [Internationalization (I18n)](#internationalization-i18n)
|
19
22
|
- [Development](#development)
|
20
23
|
- [License](#license)
|
21
24
|
- [Sponsors](#sponsors)
|
@@ -34,6 +37,8 @@ Take a look at the [DiscoveryController](app/controllers/doorkeeper/openid_conne
|
|
34
37
|
|
35
38
|
## Installation
|
36
39
|
|
40
|
+
Make sure your application is already set up with [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper#installation).
|
41
|
+
|
37
42
|
Add this line to your application's `Gemfile` and run `bundle install`:
|
38
43
|
|
39
44
|
```ruby
|
@@ -53,12 +58,16 @@ rails generate doorkeeper:openid_connect:migration
|
|
53
58
|
rake db:migrate
|
54
59
|
```
|
55
60
|
|
61
|
+
If you're upgrading from an earlier version, check [CHANGELOG.md](CHANGELOG.md) for upgrade instructions.
|
62
|
+
|
56
63
|
## Configuration
|
57
64
|
|
65
|
+
Make sure you've [configured Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper#configuration) before continuing.
|
66
|
+
|
58
67
|
Verify your settings in `config/initializers/doorkeeper.rb`:
|
59
68
|
|
60
69
|
- `resource_owner_authenticator`
|
61
|
-
-
|
70
|
+
- This callback needs to returns a falsey value if the current user can't be determined:
|
62
71
|
|
63
72
|
```ruby
|
64
73
|
resource_owner_authenticator do
|
@@ -78,10 +87,10 @@ The following settings are required in `config/initializers/doorkeeper_openid_co
|
|
78
87
|
- `subject`
|
79
88
|
- Identifier for the resource owner (i.e. the authenticated user). A locally unique and never reassigned identifier within the issuer for the end-user, which is intended to be consumed by the client. The value is a case-sensitive string and must not exceed 255 ASCII characters in length.
|
80
89
|
- The database ID of the user is an acceptable choice if you don't mind leaking that information.
|
81
|
-
- `jws_private_key
|
82
|
-
- Private
|
83
|
-
- You can generate
|
84
|
-
- You should not commit
|
90
|
+
- `jws_private_key`
|
91
|
+
- Private RSA key for [JSON Web Signature](https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31).
|
92
|
+
- You can generate a private key with the `openssl` command, see e.g. [Generate a keypair using OpenSSL](https://en.wikibooks.org/wiki/Cryptography/Generate_a_keypair_using_OpenSSL).
|
93
|
+
- You should not commit the key to your repository, but use an external file (in combination with `File.read`) and/or the [dotenv-rails](https://github.com/bkeepers/dotenv) gem (in combination with `ENV[...]`).
|
85
94
|
- `resource_owner_from_access_token`
|
86
95
|
- Defines how to translate the Doorkeeper access token to a resource owner model.
|
87
96
|
|
@@ -93,6 +102,7 @@ The following settings are optional, but recommended for better client compatibi
|
|
93
102
|
- `reauthenticate_resource_owner`
|
94
103
|
- Defines how to trigger reauthentication for the current user (e.g. display a password prompt, or sign-out the user and redirect to the login form).
|
95
104
|
- Required to support the `max_age` and `prompt=login` parameters.
|
105
|
+
- The block is executed in the controller's scope, so you have access to methods like `params`, `redirect_to` etc.
|
96
106
|
|
97
107
|
The following settings are optional:
|
98
108
|
|
@@ -100,6 +110,12 @@ The following settings are optional:
|
|
100
110
|
- Expiration time after which the ID Token must not be accepted for processing by clients.
|
101
111
|
- The default is 120 seconds
|
102
112
|
|
113
|
+
- `protocol`
|
114
|
+
- The protocol to use when generating URIs for the discovery endpoints.
|
115
|
+
- The default is `https` for production, and `http` for all other environments
|
116
|
+
- Note that the OIC specification mandates HTTPS, so you shouldn't change this
|
117
|
+
for production environments unless you have a really good reason!
|
118
|
+
|
103
119
|
### Scopes
|
104
120
|
|
105
121
|
To perform authentication over OpenID Connect, an OAuth client needs to request the `openid` scope. This scope needs to be enabled using either `optional_scopes` in the global Doorkeeper configuration in `config/initializers/doorkeeper.rb`, or by adding it to any OAuth application's `scope` attribute.
|
@@ -122,6 +138,12 @@ Doorkeeper::OpenidConnect.configure do
|
|
122
138
|
claim :full_name do |resource_owner|
|
123
139
|
"#{resource_owner.first_name} #{resource_owner.last_name}"
|
124
140
|
end
|
141
|
+
|
142
|
+
claim :preferred_username, scope: :openid do |resource_owner, application_scopes|
|
143
|
+
# Pass the resource_owner's preferred_username if the application has
|
144
|
+
# `profile` scope access. Otherwise, provide a more generic alternative.
|
145
|
+
application_scopes.exists?(:profile) ? resource_owner.preferred_username : "summer-sun-9449"
|
146
|
+
end
|
125
147
|
end
|
126
148
|
end
|
127
149
|
```
|
@@ -149,6 +171,8 @@ GET /.well-known/openid-configuration
|
|
149
171
|
GET /.well-known/webfinger
|
150
172
|
```
|
151
173
|
|
174
|
+
With the exception of the hard-coded `/.well-known` paths (see [RFC 5785](https://tools.ietf.org/html/rfc5785)) you can customize routes in the same way as with Doorkeeper, please refer to [this page on their wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-routes#version--05-1).
|
175
|
+
|
152
176
|
### Nonces
|
153
177
|
|
154
178
|
To support clients who send nonces you have to tweak Doorkeeper's authorization view so the parameter is passed on.
|
@@ -182,6 +206,10 @@ Then tweak the template as follows:
|
|
182
206
|
</div>
|
183
207
|
```
|
184
208
|
|
209
|
+
### Internationalization (I18n)
|
210
|
+
|
211
|
+
We use Rails locale files for error messages and scope descriptions, see [config/locales/en.yml](config/locales/en.yml). You can override these by adding them to your own translations in `config/locale`.
|
212
|
+
|
185
213
|
## Development
|
186
214
|
|
187
215
|
Run `bundle install` to setup all development dependencies.
|
@@ -5,7 +5,7 @@ module Doorkeeper
|
|
5
5
|
before_action -> { doorkeeper_authorize! :openid }
|
6
6
|
|
7
7
|
def show
|
8
|
-
resource_owner =
|
8
|
+
resource_owner = Doorkeeper::OpenidConnect.configuration.resource_owner_from_access_token.call(doorkeeper_token)
|
9
9
|
user_info = Doorkeeper::OpenidConnect::UserInfo.new(resource_owner, doorkeeper_token.scopes)
|
10
10
|
render json: user_info, status: :ok
|
11
11
|
end
|
data/config/locales/en.yml
CHANGED
@@ -2,9 +2,16 @@ en:
|
|
2
2
|
doorkeeper:
|
3
3
|
scopes:
|
4
4
|
openid: 'Authenticate your account'
|
5
|
+
profile: 'View your profile information'
|
6
|
+
email: 'View your email address'
|
7
|
+
address: 'View your physical address'
|
8
|
+
phone: 'View your phone number'
|
5
9
|
errors:
|
6
10
|
messages:
|
7
11
|
login_required: 'The authorization server requires end-user authentication'
|
12
|
+
consent_required: 'The authorization server requires end-user consent'
|
13
|
+
interaction_required: 'The authorization server requires end-user interaction'
|
14
|
+
account_selection_required: 'The authorization server requires end-user account selection'
|
8
15
|
openid_connect:
|
9
16
|
errors:
|
10
17
|
messages:
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.required_ruby_version = ">= 2.1"
|
21
21
|
|
22
22
|
spec.add_runtime_dependency 'doorkeeper', '~> 4.0'
|
23
|
-
spec.add_runtime_dependency 'json-jwt', '~> 1.6
|
23
|
+
spec.add_runtime_dependency 'json-jwt', '~> 1.6'
|
24
24
|
|
25
25
|
spec.add_development_dependency 'rspec-rails'
|
26
26
|
spec.add_development_dependency 'factory_girl'
|
@@ -7,18 +7,18 @@ module Doorkeeper
|
|
7
7
|
# http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
|
8
8
|
# http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
9
9
|
STANDARD_CLAIMS = {
|
10
|
-
profile: %
|
10
|
+
profile: %i[
|
11
11
|
name family_name given_name middle_name nickname preferred_username
|
12
12
|
profile picture website gender birthdate zoneinfo locale updated_at
|
13
13
|
],
|
14
|
-
email: %
|
15
|
-
address: %
|
16
|
-
phone: %
|
14
|
+
email: %i[ email email_verified ],
|
15
|
+
address: %i[ address ],
|
16
|
+
phone: %i[ phone_number phone_number_verified ],
|
17
17
|
}
|
18
18
|
|
19
19
|
def initialize(options = {})
|
20
|
-
@name = options[:name]
|
21
|
-
@scope = options[:scope]
|
20
|
+
@name = options[:name].to_sym
|
21
|
+
@scope = options[:scope].to_sym if options[:scope]
|
22
22
|
|
23
23
|
# use default scope for Standard Claims
|
24
24
|
@scope ||= STANDARD_CLAIMS.find do |_scope, claims|
|
@@ -1,22 +1,15 @@
|
|
1
1
|
module Doorkeeper
|
2
2
|
module OpenidConnect
|
3
|
-
class ConfigurationError < StandardError; end
|
4
|
-
class MissingConfiguration < StandardError
|
5
|
-
def initialize
|
6
|
-
super('Configuration for Doorkeeper OpenID Connect missing. Do you have doorkeeper_openid_connect initializer?')
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
3
|
def self.configure(&block)
|
11
4
|
if Doorkeeper.configuration.orm != :active_record
|
12
|
-
fail
|
5
|
+
fail Errors::InvalidConfiguration, 'Doorkeeper OpenID Connect currently only supports the ActiveRecord ORM adapter'
|
13
6
|
end
|
14
7
|
|
15
8
|
@config = Config::Builder.new(&block).build
|
16
9
|
end
|
17
10
|
|
18
11
|
def self.configuration
|
19
|
-
@config || (fail MissingConfiguration)
|
12
|
+
@config || (fail Errors::MissingConfiguration)
|
20
13
|
end
|
21
14
|
|
22
15
|
class Config
|
@@ -29,6 +22,10 @@ module Doorkeeper
|
|
29
22
|
def build
|
30
23
|
@config
|
31
24
|
end
|
25
|
+
|
26
|
+
def jws_public_key(*args)
|
27
|
+
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
|
+
end
|
32
29
|
end
|
33
30
|
|
34
31
|
module Option
|
@@ -95,28 +92,31 @@ module Doorkeeper
|
|
95
92
|
extend Option
|
96
93
|
|
97
94
|
option :jws_private_key
|
98
|
-
option :jws_public_key
|
99
95
|
option :issuer
|
100
96
|
|
101
97
|
option :resource_owner_from_access_token, default: lambda { |*_|
|
102
|
-
fail
|
98
|
+
fail Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.resource_owner_from_access_token_not_configured')
|
103
99
|
}
|
104
100
|
|
105
101
|
option :auth_time_from_resource_owner, default: lambda { |*_|
|
106
|
-
fail
|
102
|
+
fail Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.auth_time_from_resource_owner_not_configured')
|
107
103
|
}
|
108
104
|
|
109
105
|
option :reauthenticate_resource_owner, default: lambda { |*_|
|
110
|
-
fail
|
106
|
+
fail Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.reauthenticate_resource_owner_not_configured')
|
111
107
|
}
|
112
108
|
|
113
109
|
option :subject, default: lambda { |*_|
|
114
|
-
fail
|
110
|
+
fail Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.subject_not_configured')
|
115
111
|
}
|
116
112
|
|
117
113
|
option :expiration, default: 120
|
118
114
|
|
119
115
|
option :claims, builder_class: ClaimsBuilder
|
116
|
+
|
117
|
+
option :protocol, default: lambda { |*_|
|
118
|
+
::Rails.env.production? ? :https : :http
|
119
|
+
}
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
module Errors
|
4
|
+
class OpenidConnectError < StandardError
|
5
|
+
def error_name
|
6
|
+
self.class.name.demodulize.underscore
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# internal errors
|
11
|
+
class InvalidConfiguration < OpenidConnectError; end
|
12
|
+
class MissingConfiguration < OpenidConnectError
|
13
|
+
def initialize
|
14
|
+
super('Configuration for Doorkeeper OpenID Connect missing. Do you have doorkeeper_openid_connect initializer?')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# OAuth 2.0 errors
|
19
|
+
# https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
20
|
+
class InvalidRequest < OpenidConnectError; end
|
21
|
+
|
22
|
+
# OpenID Connect 1.0 errors
|
23
|
+
# http://openid.net/specs/openid-connect-core-1_0.html#AuthError
|
24
|
+
class LoginRequired < OpenidConnectError; end
|
25
|
+
class ConsentRequired < OpenidConnectError; end
|
26
|
+
class InteractionRequired < OpenidConnectError; end
|
27
|
+
class AccountSelectionRequired < OpenidConnectError; end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -5,42 +5,80 @@ module Doorkeeper
|
|
5
5
|
private
|
6
6
|
|
7
7
|
def authenticate_resource_owner!
|
8
|
-
|
9
|
-
|
10
|
-
owner
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def validate_prompt_param!(owner)
|
15
|
-
prompt_values ||= params[:prompt].to_s.split(/ +/)
|
16
|
-
return true unless prompt_values.include?('none') && !owner
|
8
|
+
super.tap do |owner|
|
9
|
+
next unless pre_auth.scopes.include? 'openid'
|
17
10
|
|
11
|
+
handle_prompt_param!(owner)
|
12
|
+
handle_max_age_param!(owner)
|
13
|
+
end
|
14
|
+
rescue Errors::OpenidConnectError => exception
|
18
15
|
# clear the previous response body to avoid a DoubleRenderError
|
19
16
|
self.response_body = nil
|
20
17
|
|
21
18
|
# FIXME: workaround for Rails 5, see https://github.com/rails/rails/issues/25106
|
22
19
|
@_response_body = nil
|
23
20
|
|
24
|
-
error = ::Doorkeeper::OAuth::ErrorResponse.new(name:
|
21
|
+
error = ::Doorkeeper::OAuth::ErrorResponse.new(name: exception.error_name)
|
25
22
|
response.headers.merge!(error.headers)
|
26
23
|
render json: error.body, status: error.status
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_prompt_param!(owner)
|
27
|
+
prompt_values ||= params[:prompt].to_s.split(/ +/).uniq
|
27
28
|
|
28
|
-
|
29
|
+
prompt_values.each do |prompt|
|
30
|
+
case prompt
|
31
|
+
when 'none' then
|
32
|
+
raise Errors::InvalidRequest if (prompt_values - [ 'none' ]).any?
|
33
|
+
raise Errors::LoginRequired unless owner
|
34
|
+
raise Errors::ConsentRequired unless matching_tokens_for_resource_owner(owner).present?
|
35
|
+
when 'login' then
|
36
|
+
reauthenticate_resource_owner(owner) if owner
|
37
|
+
when 'consent' then
|
38
|
+
matching_tokens_for_resource_owner(owner).map(&:destroy)
|
39
|
+
when 'select_account' then
|
40
|
+
# TODO: let the user implement this
|
41
|
+
raise Errors::AccountSelectionRequired
|
42
|
+
else
|
43
|
+
raise Errors::InvalidRequest
|
44
|
+
end
|
45
|
+
end
|
29
46
|
end
|
30
47
|
|
31
|
-
def
|
48
|
+
def handle_max_age_param!(owner)
|
32
49
|
max_age = params[:max_age].to_i
|
33
|
-
return
|
50
|
+
return unless max_age > 0 && owner
|
34
51
|
|
35
52
|
auth_time = instance_exec owner,
|
36
53
|
&Doorkeeper::OpenidConnect.configuration.auth_time_from_resource_owner
|
37
54
|
|
38
55
|
if !auth_time || (Time.zone.now - auth_time) > max_age
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
56
|
+
reauthenticate_resource_owner(owner)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def reauthenticate_resource_owner(owner)
|
61
|
+
return_to = URI.parse(request.path)
|
62
|
+
return_to.query = request.query_parameters.tap do |params|
|
63
|
+
params['prompt'] = params['prompt'].to_s.sub(/\blogin\s*\b/, '').strip
|
64
|
+
params.delete('prompt') if params['prompt'].blank?
|
65
|
+
end.to_query
|
66
|
+
|
67
|
+
instance_exec owner, return_to.to_s,
|
68
|
+
&Doorkeeper::OpenidConnect.configuration.reauthenticate_resource_owner
|
69
|
+
|
70
|
+
raise Errors::LoginRequired unless performed?
|
71
|
+
end
|
72
|
+
|
73
|
+
def matching_tokens_for_resource_owner(owner)
|
74
|
+
# TODO: maybe use Doorkeeper::AccessToken.matching_token_for once
|
75
|
+
# https://github.com/doorkeeper-gem/doorkeeper/pull/907 is merged
|
76
|
+
Doorkeeper::AccessToken.where(
|
77
|
+
application_id: pre_auth.client.id,
|
78
|
+
resource_owner_id: owner.id,
|
79
|
+
revoked_at: nil,
|
80
|
+
).select do |token|
|
81
|
+
Doorkeeper::AccessToken.scopes_match?(token.scopes, pre_auth.scopes, nil)
|
44
82
|
end
|
45
83
|
end
|
46
84
|
end
|
@@ -8,7 +8,7 @@ module Doorkeeper
|
|
8
8
|
def initialize(access_token, nonce = nil)
|
9
9
|
@access_token = access_token
|
10
10
|
@nonce = nonce
|
11
|
-
@resource_owner =
|
11
|
+
@resource_owner = Doorkeeper::OpenidConnect.configuration.resource_owner_from_access_token.call(access_token)
|
12
12
|
@issued_at = Time.now
|
13
13
|
end
|
14
14
|
|
@@ -25,7 +25,7 @@ module Doorkeeper
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def as_json(*_)
|
28
|
-
claims.reject { |_, value| value.
|
28
|
+
claims.reject { |_, value| value.nil? || value == '' }
|
29
29
|
end
|
30
30
|
|
31
31
|
def as_jws_token
|
@@ -39,7 +39,7 @@ module Doorkeeper
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def subject
|
42
|
-
|
42
|
+
Doorkeeper::OpenidConnect.configuration.subject.call(@resource_owner).to_s
|
43
43
|
end
|
44
44
|
|
45
45
|
def audience
|
@@ -55,7 +55,7 @@ module Doorkeeper
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def auth_time
|
58
|
-
|
58
|
+
Doorkeeper::OpenidConnect.configuration.auth_time_from_resource_owner.call(@resource_owner).try(:to_i)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -13,7 +13,7 @@ module Doorkeeper
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def as_json(*_)
|
16
|
-
claims
|
16
|
+
claims.reject { |_, value| value.nil? || value == '' }
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
@@ -27,13 +27,13 @@ module Doorkeeper
|
|
27
27
|
def resource_owner_claims
|
28
28
|
Doorkeeper::OpenidConnect.configuration.claims.to_h.map do |name, claim|
|
29
29
|
if @scopes.exists? claim.scope
|
30
|
-
[name,
|
30
|
+
[name, claim.generator.call(@resource_owner, @scopes)]
|
31
31
|
end
|
32
32
|
end.compact.to_h
|
33
33
|
end
|
34
34
|
|
35
35
|
def subject
|
36
|
-
|
36
|
+
Doorkeeper::OpenidConnect.configuration.subject.call(@resource_owner).to_s
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -7,6 +7,7 @@ require 'doorkeeper/openid_connect/claims/claim'
|
|
7
7
|
require 'doorkeeper/openid_connect/claims/normal_claim'
|
8
8
|
require 'doorkeeper/openid_connect/config'
|
9
9
|
require 'doorkeeper/openid_connect/engine'
|
10
|
+
require 'doorkeeper/openid_connect/errors'
|
10
11
|
require 'doorkeeper/openid_connect/id_token'
|
11
12
|
require 'doorkeeper/openid_connect/user_info'
|
12
13
|
require 'doorkeeper/openid_connect/version'
|
@@ -5,12 +5,6 @@ Doorkeeper::OpenidConnect.configure do
|
|
5
5
|
-----BEGIN RSA PRIVATE KEY-----
|
6
6
|
....
|
7
7
|
-----END RSA PRIVATE KEY-----
|
8
|
-
EOL
|
9
|
-
|
10
|
-
jws_public_key <<-EOL
|
11
|
-
-----BEGIN RSA PUBLIC KEY-----
|
12
|
-
....
|
13
|
-
-----END RSA PUBLIC KEY-----
|
14
8
|
EOL
|
15
9
|
|
16
10
|
resource_owner_from_access_token do |access_token|
|
@@ -23,9 +17,9 @@ EOL
|
|
23
17
|
# resource_owner.current_sign_in_at
|
24
18
|
end
|
25
19
|
|
26
|
-
reauthenticate_resource_owner do |resource_owner|
|
20
|
+
reauthenticate_resource_owner do |resource_owner, return_to|
|
27
21
|
# Example implementation:
|
28
|
-
# store_location_for resource_owner,
|
22
|
+
# store_location_for resource_owner, return_to
|
29
23
|
# sign_out resource_owner
|
30
24
|
# redirect_to new_user_session_url
|
31
25
|
end
|
@@ -35,6 +29,12 @@ EOL
|
|
35
29
|
# resource_owner.key
|
36
30
|
end
|
37
31
|
|
32
|
+
# Protocol to use when generating URIs for the discovery endpoint,
|
33
|
+
# for example if you also use HTTPS in development
|
34
|
+
# protocol do
|
35
|
+
# :https
|
36
|
+
# end
|
37
|
+
|
38
38
|
# Expiration time on or after which the ID Token MUST NOT be accepted for processing. (default 120 seconds).
|
39
39
|
# expiration 600
|
40
40
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doorkeeper-openid_connect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Dengler
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-01-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: doorkeeper
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 1.6
|
34
|
+
version: '1.6'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 1.6
|
41
|
+
version: '1.6'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rspec-rails
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- lib/doorkeeper/openid_connect/claims_builder.rb
|
141
141
|
- lib/doorkeeper/openid_connect/config.rb
|
142
142
|
- lib/doorkeeper/openid_connect/engine.rb
|
143
|
+
- lib/doorkeeper/openid_connect/errors.rb
|
143
144
|
- lib/doorkeeper/openid_connect/helpers/controller.rb
|
144
145
|
- lib/doorkeeper/openid_connect/id_token.rb
|
145
146
|
- lib/doorkeeper/openid_connect/oauth/authorization/code.rb
|
@@ -179,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
180
|
version: '0'
|
180
181
|
requirements: []
|
181
182
|
rubyforge_project:
|
182
|
-
rubygems_version: 2.5.
|
183
|
+
rubygems_version: 2.5.2
|
183
184
|
signing_key:
|
184
185
|
specification_version: 4
|
185
186
|
summary: OpenID Connect extension for Doorkeeper.
|