doorkeeper-openid_connect 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.