doorkeeper-openid_connect 1.1.2 → 1.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb8f0c135989160ec85abaf36372b7c2c26555dc
4
- data.tar.gz: 6e90f7e3ec846f681ca07812dff8598b487d3823
3
+ metadata.gz: 219908f8f6caf6cde4e1eeec48f764e6492afa08
4
+ data.tar.gz: ab569c90cf0681143d2c470dcebdb906644f082f
5
5
  SHA512:
6
- metadata.gz: 151b1bb6832b6d9b9f9a0ef6bd7ff4d964fbd242b65c085050e5a000a5230697bfc028be27158aa618060ca2cc557cc7865279fcf0657a87dd214f3f6e7fdc63
7
- data.tar.gz: 0eb9415cb8a01c978d494cefd82fc495bf76230b77e849a979270ce899049bed45c8ee0b7e1e130e41f1fcf2e84814c61a3c8914d48e5ec35ee0591d034a5f64
6
+ metadata.gz: 47affadec9efd1dd9b81b858b0e1e267a5fdbb5b930331caaa7e237a7312030f4d6ef78264069c6b1f0b21b25a7ca175583db3ca4a9bab48c49c5a5c2bd86837
7
+ data.tar.gz: 353324e6e880db3ae6af6987a2873173160ed350f41c8f26e38bcb4b6d53a2bac93f4fe2e5a01dd347fc6ab71081a6d6a419c342d90c9aabfcd0f7f683d5aacc
data/.travis.yml CHANGED
@@ -17,8 +17,9 @@ env:
17
17
 
18
18
  rvm:
19
19
  - 2.1
20
- - 2.2.5
21
- - 2.3.1
20
+ - 2.2.7
21
+ - 2.3.4
22
+ - 2.4.1
22
23
 
23
24
  matrix:
24
25
  exclude:
data/CHANGELOG.md CHANGED
@@ -1,6 +1,17 @@
1
- ### Unreleased
1
+ <a name="v1.2.0"></a>
2
+ ### v1.2.0 (2017-08-31)
2
3
 
3
- #### Changes
4
+ ### Upgrading
5
+
6
+ - The configuration setting `jws_private_key` was renamed to `signing_key`, you can still use the old name until it's removed in the next major release
7
+
8
+ ### Features
9
+
10
+ - Support for pairwise subject identifiers (by @travisofthenorth)
11
+ - Support for EC and HMAC signing algorithms (by @110y)
12
+ - Claims now receive an optional third `access_token` argument which allow you to dynamically adjust claim values based on the client's token (by @gigr)
13
+
14
+ ### Bugfixes
4
15
 
5
16
  <a name="v1.1.2"></a>
6
17
  ### v1.1.2 (2017-01-18)
data/CONTRIBUTING.md CHANGED
@@ -9,7 +9,7 @@ Our first line of defense is the [Travis CI](https://travis-ci.org/doorkeeper-ge
9
9
  Create a feature branch:
10
10
 
11
11
  ```sh
12
- git checkout -B feat/contributing
12
+ git checkout -B feature/contributing
13
13
  ```
14
14
 
15
15
  ## Creating Good Commits
@@ -47,7 +47,7 @@ We use commit messages as per [Conventional Changelog](https://github.com/conven
47
47
 
48
48
  Allowed types:
49
49
 
50
- * **feat**: A new feature
50
+ * **feature**: A new feature
51
51
  * **fix**: A bug fix
52
52
  * **docs**: Documentation only changes
53
53
  * **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, newline, line endings, etc)
@@ -59,7 +59,7 @@ Allowed types:
59
59
  You can add additional details after a new line to describe the change in detail or automatically close an issue on GitHub.
60
60
 
61
61
  ```none
62
- feat: create initial CONTRIBUTING.md
62
+ feature: create initial CONTRIBUTING.md
63
63
 
64
64
  This closes #73
65
65
  ```
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
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
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/).
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/m0n9oose/omniauth_openid_connect/).
11
11
 
12
12
  ## Table of Contents
13
13
 
@@ -87,10 +87,27 @@ The following settings are required in `config/initializers/doorkeeper_openid_co
87
87
  - `subject`
88
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.
89
89
  - The database ID of the user is an acceptable choice if you don't mind leaking that information.
90
+ - If you want to provide a different subject identifier to each client, use [pairwise subject identifier](http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes) with configurations like below.
91
+
92
+ ```ruby
93
+ # config/initializers/doorkeeper_openid_connect.rb
94
+ Doorkeeper::OpenidConnect.configure do
95
+ # ...
96
+ subject_types_supported [:pairwise]
97
+
98
+ subject do |resource_owner, application|
99
+ Digest::SHA256.hexdigest("#{resource_owner.id}#{URI.parse(application.redirect_uri).host}#{'your_secret_salt'}")
100
+ end
101
+ # ...
102
+ end
103
+ ```
104
+
90
105
  - `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).
106
+ - Private key for [JSON Web Signature](https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31).
107
+ - You can generate a private key with the `openssl` command, see e.g. [Generate an RSA keypair using OpenSSL](https://en.wikibooks.org/wiki/Cryptography/Generate_a_keypair_using_OpenSSL).
93
108
  - 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[...]`).
109
+ - `signing_algorithm`
110
+ - The encryption type of the private key which defaults to `:rs256`. The list of supported algorithms can be found [here](https://github.com/nov/json-jwt/wiki/JWE#supported-algorithms)
94
111
  - `resource_owner_from_access_token`
95
112
  - Defines how to translate the Doorkeeper access token to a resource owner model.
96
113
 
@@ -139,7 +156,7 @@ Doorkeeper::OpenidConnect.configure do
139
156
  "#{resource_owner.first_name} #{resource_owner.last_name}"
140
157
  end
141
158
 
142
- claim :preferred_username, scope: :openid do |resource_owner, application_scopes|
159
+ claim :preferred_username, scope: :openid do |resource_owner, application_scopes, access_token|
143
160
  # Pass the resource_owner's preferred_username if the application has
144
161
  # `profile` scope access. Otherwise, provide a more generic alternative.
145
162
  application_scopes.exists?(:profile) ? resource_owner.preferred_username : "summer-sun-9449"
@@ -44,14 +44,10 @@ module Doorkeeper
44
44
  #'private_key_jwt'
45
45
  ],
46
46
 
47
- # TODO: make this configurable
48
- subject_types_supported: [
49
- 'public',
50
- ],
47
+ subject_types_supported: openid_connect.subject_types_supported,
51
48
 
52
- # TODO: make this configurable
53
49
  id_token_signing_alg_values_supported: [
54
- 'RS256',
50
+ ::Doorkeeper::OpenidConnect.signing_algorithm
55
51
  ],
56
52
 
57
53
  claim_types_supported: [
@@ -85,13 +81,13 @@ module Doorkeeper
85
81
  end
86
82
 
87
83
  def keys_response
88
- signing_key = Doorkeeper::OpenidConnect.signing_key
84
+ signing_key = Doorkeeper::OpenidConnect.signing_key_normalized
89
85
 
90
86
  {
91
87
  keys: [
92
- signing_key.slice(:kty, :kid, :e, :n).merge(
88
+ signing_key.merge(
93
89
  use: 'sig',
94
- alg: Doorkeeper::OpenidConnect::SIGNING_ALGORITHM
90
+ alg: Doorkeeper::OpenidConnect.signing_algorithm
95
91
  )
96
92
  ]
97
93
  }
@@ -5,9 +5,7 @@ module Doorkeeper
5
5
  before_action -> { doorkeeper_authorize! :openid }
6
6
 
7
7
  def show
8
- resource_owner = Doorkeeper::OpenidConnect.configuration.resource_owner_from_access_token.call(doorkeeper_token)
9
- user_info = Doorkeeper::OpenidConnect::UserInfo.new(resource_owner, doorkeeper_token.scopes)
10
- render json: user_info, status: :ok
8
+ render json: Doorkeeper::OpenidConnect::UserInfo.new(doorkeeper_token), status: :ok
11
9
  end
12
10
  end
13
11
  end
@@ -26,6 +26,11 @@ module Doorkeeper
26
26
  def jws_public_key(*args)
27
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
28
  end
29
+
30
+ def jws_private_key(*args)
31
+ 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
+ signing_key(*args)
33
+ end
29
34
  end
30
35
 
31
36
  module Option
@@ -91,8 +96,10 @@ module Doorkeeper
91
96
 
92
97
  extend Option
93
98
 
94
- option :jws_private_key
95
99
  option :issuer
100
+ option :signing_key
101
+ option :signing_algorithm, default: :rs256
102
+ option :subject_types_supported, default: [:public]
96
103
 
97
104
  option :resource_owner_from_access_token, default: lambda { |*_|
98
105
  fail Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.resource_owner_from_access_token_not_configured')
@@ -29,7 +29,10 @@ module Doorkeeper
29
29
  end
30
30
 
31
31
  def as_jws_token
32
- JSON::JWT.new(as_json).sign(Doorkeeper::OpenidConnect.signing_key).to_s
32
+ JSON::JWT.new(as_json).sign(
33
+ Doorkeeper::OpenidConnect.signing_key,
34
+ Doorkeeper::OpenidConnect.signing_algorithm
35
+ ).to_s
33
36
  end
34
37
 
35
38
  private
@@ -39,7 +42,7 @@ module Doorkeeper
39
42
  end
40
43
 
41
44
  def subject
42
- Doorkeeper::OpenidConnect.configuration.subject.call(@resource_owner).to_s
45
+ Doorkeeper::OpenidConnect.configuration.subject.call(@resource_owner, @access_token.application).to_s
43
46
  end
44
47
 
45
48
  def audience
@@ -3,9 +3,8 @@ module Doorkeeper
3
3
  class UserInfo
4
4
  include ActiveModel::Validations
5
5
 
6
- def initialize(resource_owner, scopes)
7
- @resource_owner = resource_owner
8
- @scopes = scopes
6
+ def initialize(access_token)
7
+ @access_token = access_token
9
8
  end
10
9
 
11
10
  def claims
@@ -26,14 +25,26 @@ module Doorkeeper
26
25
 
27
26
  def resource_owner_claims
28
27
  Doorkeeper::OpenidConnect.configuration.claims.to_h.map do |name, claim|
29
- if @scopes.exists? claim.scope
30
- [name, claim.generator.call(@resource_owner, @scopes)]
28
+ if scopes.exists? claim.scope
29
+ [name, claim.generator.call(resource_owner, scopes, @access_token)]
31
30
  end
32
31
  end.compact.to_h
33
32
  end
34
33
 
35
34
  def subject
36
- Doorkeeper::OpenidConnect.configuration.subject.call(@resource_owner).to_s
35
+ Doorkeeper::OpenidConnect.configuration.subject.call(resource_owner, application).to_s
36
+ end
37
+
38
+ def resource_owner
39
+ @resource_owner ||= Doorkeeper::OpenidConnect.configuration.resource_owner_from_access_token.call(@access_token)
40
+ end
41
+
42
+ def application
43
+ @application ||= @access_token.application
44
+ end
45
+
46
+ def scopes
47
+ @scopes ||= @access_token.scopes
37
48
  end
38
49
  end
39
50
  end
@@ -1,5 +1,5 @@
1
1
  module Doorkeeper
2
2
  module OpenidConnect
3
- VERSION = '1.1.2'.freeze
3
+ VERSION = '1.2.0'.freeze
4
4
  end
5
5
  end
@@ -26,11 +26,30 @@ require 'doorkeeper/openid_connect/rails/routes'
26
26
 
27
27
  module Doorkeeper
28
28
  module OpenidConnect
29
- # TODO: make this configurable
30
- SIGNING_ALGORITHM = 'RS256'.freeze
29
+ def self.signing_algorithm
30
+ configuration.signing_algorithm.to_s.upcase.to_sym
31
+ end
31
32
 
32
33
  def self.signing_key
33
- JSON::JWK.new(OpenSSL::PKey.read(configuration.jws_private_key))
34
+ key =
35
+ if [:HS256, :HS384, :HS512].include?(signing_algorithm)
36
+ configuration.signing_key
37
+ else
38
+ OpenSSL::PKey.read(configuration.signing_key)
39
+ end
40
+ JSON::JWK.new(key)
41
+ end
42
+
43
+ def self.signing_key_normalized
44
+ key = signing_key
45
+ case key[:kty].to_sym
46
+ when :RSA
47
+ key.slice(:kty, :kid, :e, :n)
48
+ when :EC
49
+ key.slice(:kty, :kid, :x, :y)
50
+ when :oct
51
+ key.slice(:kty, :kid)
52
+ end
34
53
  end
35
54
  end
36
55
  end
@@ -1,12 +1,14 @@
1
1
  Doorkeeper::OpenidConnect.configure do
2
2
  issuer 'issuer string'
3
3
 
4
- jws_private_key <<-EOL
4
+ signing_key <<-EOL
5
5
  -----BEGIN RSA PRIVATE KEY-----
6
6
  ....
7
7
  -----END RSA PRIVATE KEY-----
8
8
  EOL
9
9
 
10
+ subject_types_supported [:public]
11
+
10
12
  resource_owner_from_access_token do |access_token|
11
13
  # Example implementation:
12
14
  # User.find_by(id: access_token.resource_owner_id)
@@ -24,9 +26,12 @@ EOL
24
26
  # redirect_to new_user_session_url
25
27
  end
26
28
 
27
- subject do |resource_owner|
29
+ subject do |resource_owner, application|
28
30
  # Example implementation:
29
- # resource_owner.key
31
+ # resource_owner.id
32
+
33
+ # or if you need pairwise subject identifier, implement like below:
34
+ # Digest::SHA256.hexdigest("#{resource_owner.id}#{URI.parse(application.redirect_uri).host}#{'your_secret_salt'}")
30
35
  end
31
36
 
32
37
  # Protocol to use when generating URIs for the discovery endpoint,
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.2
4
+ version: 1.2.0
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: 2017-01-18 00:00:00.000000000 Z
12
+ date: 2017-08-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: doorkeeper
@@ -180,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
180
  version: '0'
181
181
  requirements: []
182
182
  rubyforge_project:
183
- rubygems_version: 2.5.2
183
+ rubygems_version: 2.6.10
184
184
  signing_key:
185
185
  specification_version: 4
186
186
  summary: OpenID Connect extension for Doorkeeper.