doorkeeper-openid_connect 1.2.0 → 1.3.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/CONTRIBUTING.md +0 -27
- data/README.md +14 -1
- data/doorkeeper-openid_connect.gemspec +1 -1
- data/lib/doorkeeper/oauth/id_token_request.rb +41 -0
- data/lib/doorkeeper/oauth/id_token_response.rb +28 -0
- data/lib/doorkeeper/oauth/id_token_token_request.rb +13 -0
- data/lib/doorkeeper/oauth/id_token_token_response.rb +16 -0
- data/lib/doorkeeper/openid_connect.rb +10 -0
- data/lib/doorkeeper/openid_connect/id_token.rb +1 -1
- data/lib/doorkeeper/openid_connect/id_token_token.rb +33 -0
- data/lib/doorkeeper/openid_connect/oauth/authorization/token.rb +22 -0
- data/lib/doorkeeper/openid_connect/orm/active_record.rb +9 -5
- data/lib/doorkeeper/openid_connect/response_types_config.rb +17 -0
- data/lib/doorkeeper/openid_connect/version.rb +1 -1
- data/lib/doorkeeper/request/id_token.rb +17 -0
- data/lib/doorkeeper/request/id_token_token.rb +17 -0
- metadata +13 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3533bb17ae7ec3e41b8c43eac5bd78cc34a9aed3
|
4
|
+
data.tar.gz: bfe300fda2bd2658eec78cc74c33f2c63856d121
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 348b4ea59e13c2a1597d2d85a2961b183c0088c64d3f055539f13175c33d7269e7e66d70c1f4fa87a17ba8627ce8548d7070809274f0abf47476f90dc38e0a0f
|
7
|
+
data.tar.gz: cad47c48ac11b98c657706815748cae81eb8cba177fbfa1b1369cc9c21f26eb7000aff5e46ecb231e55fb8811ffdd1e4ea13952f3421e8c614ff341cba736489
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
<a name="v1.3.0"></a>
|
2
|
+
### v1.3.0 (2018-03-05)
|
3
|
+
|
4
|
+
### Features
|
5
|
+
|
6
|
+
- Support for Implicit Flow (`response_type=id_token` and `response_type=id_token token`),
|
7
|
+
see the updated README for usage instructions (by @nashby, @nhance and @stevenvegt)
|
8
|
+
|
1
9
|
<a name="v1.2.0"></a>
|
2
10
|
### v1.2.0 (2017-08-31)
|
3
11
|
|
data/CONTRIBUTING.md
CHANGED
@@ -37,33 +37,6 @@ Things to avoid when creating commits:
|
|
37
37
|
* Mixing two unrelated functional changes.
|
38
38
|
* Sending large new features in a single giant commit.
|
39
39
|
|
40
|
-
## Commit Message Conventions
|
41
|
-
|
42
|
-
We use commit messages as per [Conventional Changelog](https://github.com/conventional-changelog/conventional-changelog):
|
43
|
-
|
44
|
-
```none
|
45
|
-
<type>(<scope>): <subject>
|
46
|
-
```
|
47
|
-
|
48
|
-
Allowed types:
|
49
|
-
|
50
|
-
* **feature**: A new feature
|
51
|
-
* **fix**: A bug fix
|
52
|
-
* **docs**: Documentation only changes
|
53
|
-
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, newline, line endings, etc)
|
54
|
-
* **refactor**: A code change that neither fixes a bug or adds a feature
|
55
|
-
* **perf**: A code change that improves performance
|
56
|
-
* **test**: Adding missing tests
|
57
|
-
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation generation
|
58
|
-
|
59
|
-
You can add additional details after a new line to describe the change in detail or automatically close an issue on GitHub.
|
60
|
-
|
61
|
-
```none
|
62
|
-
feature: create initial CONTRIBUTING.md
|
63
|
-
|
64
|
-
This closes #73
|
65
|
-
```
|
66
|
-
|
67
40
|
## Release process
|
68
41
|
|
69
42
|
- Bump version in `lib/doorkeeper/openid_connect/version.rb`
|
data/README.md
CHANGED
@@ -12,6 +12,7 @@ OpenID Connect is a single-sign-on and identity layer with a [growing list of se
|
|
12
12
|
## Table of Contents
|
13
13
|
|
14
14
|
- [Status](#status)
|
15
|
+
- [Example Applications](#example-applications)
|
15
16
|
- [Installation](#installation)
|
16
17
|
- [Configuration](#configuration)
|
17
18
|
- [Scopes](#scopes)
|
@@ -27,6 +28,7 @@ OpenID Connect is a single-sign-on and identity layer with a [growing list of se
|
|
27
28
|
|
28
29
|
The following parts of [OpenID Connect Core 1.0](http://openid.net/specs/openid-connect-core-1_0.html) are currently supported:
|
29
30
|
- [Authentication using the Authorization Code Flow](http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
|
31
|
+
- [Implicit Flow](http://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth)
|
30
32
|
- [Requesting Claims using Scope Values](http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims)
|
31
33
|
- [UserInfo Endpoint](http://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
|
32
34
|
- [Normal Claims](http://openid.net/specs/openid-connect-core-1_0.html#NormalClaims)
|
@@ -35,6 +37,11 @@ In addition we also support most of [OpenID Connect Discovery 1.0](http://openid
|
|
35
37
|
|
36
38
|
Take a look at the [DiscoveryController](app/controllers/doorkeeper/openid_connect/discovery_controller.rb) for more details on supported features.
|
37
39
|
|
40
|
+
### Example Applications
|
41
|
+
|
42
|
+
- [GitLab](https://gitlab.com/gitlab-org/gitlab-ce) ([original MR](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8018))
|
43
|
+
- [Testing app for this gem](https://github.com/doorkeeper-gem/doorkeeper-openid_connect/tree/master/spec/dummy)
|
44
|
+
|
38
45
|
## Installation
|
39
46
|
|
40
47
|
Make sure your application is already set up with [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper#installation).
|
@@ -79,6 +86,12 @@ Verify your settings in `config/initializers/doorkeeper.rb`:
|
|
79
86
|
end
|
80
87
|
end
|
81
88
|
```
|
89
|
+
- `grant_flows`
|
90
|
+
- If you want to use `id_token` or `id_token token` response types you need to add `implicit_oidc` to `grant_flows`:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
grant_flows %w(authorization_code implicit_oidc)
|
94
|
+
```
|
82
95
|
|
83
96
|
The following settings are required in `config/initializers/doorkeeper_openid_connect.rb`:
|
84
97
|
|
@@ -90,7 +103,7 @@ The following settings are required in `config/initializers/doorkeeper_openid_co
|
|
90
103
|
- 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
104
|
|
92
105
|
```ruby
|
93
|
-
# config/initializers/doorkeeper_openid_connect.rb
|
106
|
+
# config/initializers/doorkeeper_openid_connect.rb
|
94
107
|
Doorkeeper::OpenidConnect.configure do
|
95
108
|
# ...
|
96
109
|
subject_types_supported [:pairwise]
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.required_ruby_version = ">= 2.1"
|
21
21
|
|
22
|
-
spec.add_runtime_dependency 'doorkeeper', '~> 4.
|
22
|
+
spec.add_runtime_dependency 'doorkeeper', '~> 4.3'
|
23
23
|
spec.add_runtime_dependency 'json-jwt', '~> 1.6'
|
24
24
|
|
25
25
|
spec.add_development_dependency 'rspec-rails'
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OAuth
|
3
|
+
class IdTokenRequest
|
4
|
+
attr_accessor :pre_auth, :auth, :resource_owner
|
5
|
+
|
6
|
+
def initialize(pre_auth, resource_owner)
|
7
|
+
@pre_auth = pre_auth
|
8
|
+
@resource_owner = resource_owner
|
9
|
+
end
|
10
|
+
|
11
|
+
def authorize
|
12
|
+
if pre_auth.authorizable?
|
13
|
+
@auth = Authorization::Token.new(pre_auth, resource_owner)
|
14
|
+
@auth.issue_token
|
15
|
+
@response = response
|
16
|
+
else
|
17
|
+
@response = error_response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def deny
|
22
|
+
pre_auth.error = :access_denied
|
23
|
+
error_response
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def response
|
29
|
+
id_token = Doorkeeper::OpenidConnect::IdToken.new(auth.token, pre_auth.nonce)
|
30
|
+
|
31
|
+
IdTokenResponse.new(pre_auth, auth, id_token)
|
32
|
+
end
|
33
|
+
|
34
|
+
def error_response
|
35
|
+
ErrorResponse.from_request pre_auth,
|
36
|
+
redirect_uri: pre_auth.redirect_uri,
|
37
|
+
response_on_fragment: true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OAuth
|
3
|
+
class IdTokenResponse < BaseResponse
|
4
|
+
include OAuth::Helpers
|
5
|
+
|
6
|
+
attr_accessor :pre_auth, :auth, :id_token
|
7
|
+
|
8
|
+
def initialize(pre_auth, auth, id_token)
|
9
|
+
@pre_auth = pre_auth
|
10
|
+
@auth = auth
|
11
|
+
@id_token = id_token
|
12
|
+
end
|
13
|
+
|
14
|
+
def redirectable?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def redirect_uri
|
19
|
+
Authorization::URIBuilder.uri_with_fragment(
|
20
|
+
pre_auth.redirect_uri,
|
21
|
+
expires_in: auth.token.expires_in_seconds,
|
22
|
+
state: pre_auth.state,
|
23
|
+
id_token: id_token.as_jws_token
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OAuth
|
3
|
+
class IdTokenTokenRequest < IdTokenRequest
|
4
|
+
private
|
5
|
+
|
6
|
+
def response
|
7
|
+
id_token_token = Doorkeeper::OpenidConnect::IdTokenToken.new(auth.token, pre_auth.nonce)
|
8
|
+
|
9
|
+
IdTokenTokenResponse.new(pre_auth, auth, id_token_token)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OAuth
|
3
|
+
class IdTokenTokenResponse < IdTokenResponse
|
4
|
+
def redirect_uri
|
5
|
+
Authorization::URIBuilder.uri_with_fragment(
|
6
|
+
pre_auth.redirect_uri,
|
7
|
+
access_token: auth.token.token,
|
8
|
+
token_type: auth.token.token_type,
|
9
|
+
expires_in: auth.token.expires_in_seconds,
|
10
|
+
state: pre_auth.state,
|
11
|
+
id_token: id_token.as_jws_token
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -2,13 +2,23 @@ require 'doorkeeper'
|
|
2
2
|
require 'active_model'
|
3
3
|
require 'json/jwt'
|
4
4
|
|
5
|
+
require 'doorkeeper/request'
|
6
|
+
require 'doorkeeper/request/id_token'
|
7
|
+
require 'doorkeeper/request/id_token_token'
|
8
|
+
require 'doorkeeper/oauth/id_token_request'
|
9
|
+
require 'doorkeeper/oauth/id_token_token_request'
|
10
|
+
require 'doorkeeper/oauth/id_token_response'
|
11
|
+
require 'doorkeeper/oauth/id_token_token_response'
|
12
|
+
|
5
13
|
require 'doorkeeper/openid_connect/claims_builder'
|
6
14
|
require 'doorkeeper/openid_connect/claims/claim'
|
7
15
|
require 'doorkeeper/openid_connect/claims/normal_claim'
|
8
16
|
require 'doorkeeper/openid_connect/config'
|
17
|
+
require 'doorkeeper/openid_connect/response_types_config'
|
9
18
|
require 'doorkeeper/openid_connect/engine'
|
10
19
|
require 'doorkeeper/openid_connect/errors'
|
11
20
|
require 'doorkeeper/openid_connect/id_token'
|
21
|
+
require 'doorkeeper/openid_connect/id_token_token'
|
12
22
|
require 'doorkeeper/openid_connect/user_info'
|
13
23
|
require 'doorkeeper/openid_connect/version'
|
14
24
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
class IdTokenToken < IdToken
|
4
|
+
def claims
|
5
|
+
super.merge(at_hash: at_hash)
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# The at_hash is build according to the following standard:
|
11
|
+
#
|
12
|
+
# http://openid.net/specs/openid-connect-implicit-1_0.html#IDToken
|
13
|
+
#
|
14
|
+
# at_hash:
|
15
|
+
# REQUIRED. Access Token hash value. If the ID Token is issued with an
|
16
|
+
# access_token in an Implicit Flow, this is REQUIRED, which is the case
|
17
|
+
# for this subset of OpenID Connect. Its value is the base64url encoding
|
18
|
+
# of the left-most half of the hash of the octets of the ASCII
|
19
|
+
# representation of the access_token value, where the hash algorithm
|
20
|
+
# used is the hash algorithm used in the alg Header Parameter of the
|
21
|
+
# ID Token's JOSE Header. For instance, if the alg is RS256, hash the
|
22
|
+
# access_token value with SHA-256, then take the left-most 128 bits and
|
23
|
+
# base64url-encode them. The at_hash value is a case-sensitive string.
|
24
|
+
def at_hash
|
25
|
+
sha256 = Digest::SHA256.new
|
26
|
+
token = @access_token.token
|
27
|
+
hashed_token = sha256.digest(token)
|
28
|
+
first_half = hashed_token[0...hashed_token.length / 2]
|
29
|
+
Base64.urlsafe_encode64(first_half).tr('=', '')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
module OAuth
|
4
|
+
module Authorization
|
5
|
+
module Code
|
6
|
+
def issue_token
|
7
|
+
super.tap do |access_grant|
|
8
|
+
if pre_auth.nonce.present?
|
9
|
+
::Doorkeeper::OpenidConnect::Request.create!(
|
10
|
+
access_grant: access_grant,
|
11
|
+
nonce: pre_auth.nonce
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
OAuth::Authorization::Code.send :prepend, OpenidConnect::OAuth::Authorization::Code
|
22
|
+
end
|
@@ -1,15 +1,19 @@
|
|
1
|
+
require 'active_support/lazy_load_hooks'
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module OpenidConnect
|
3
5
|
module Orm
|
4
6
|
module ActiveRecord
|
5
7
|
def initialize_models!
|
6
8
|
super
|
7
|
-
|
8
|
-
|
9
|
+
ActiveSupport.on_load(:active_record) do
|
10
|
+
require 'doorkeeper/openid_connect/orm/active_record/access_grant'
|
11
|
+
require 'doorkeeper/openid_connect/orm/active_record/request'
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
if Doorkeeper.configuration.active_record_options[:establish_connection]
|
14
|
+
[Doorkeeper::OpenidConnect::Request].each do |c|
|
15
|
+
c.send :establish_connection, Doorkeeper.configuration.active_record_options[:establish_connection]
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
module ResponseTypeConfig
|
4
|
+
private def calculate_authorization_response_types
|
5
|
+
types = super
|
6
|
+
if grant_flows.include? 'implicit_oidc'
|
7
|
+
types << 'token'
|
8
|
+
types << 'id_token'
|
9
|
+
types << 'id_token token'
|
10
|
+
end
|
11
|
+
types
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Config.send :prepend, OpenidConnect::ResponseTypeConfig
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'doorkeeper/request/strategy'
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module Request
|
5
|
+
class IdToken < Strategy
|
6
|
+
delegate :current_resource_owner, to: :server
|
7
|
+
|
8
|
+
def pre_auth
|
9
|
+
server.context.send(:pre_auth)
|
10
|
+
end
|
11
|
+
|
12
|
+
def request
|
13
|
+
@request ||= OAuth::IdTokenRequest.new(pre_auth, current_resource_owner)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'doorkeeper/request/strategy'
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module Request
|
5
|
+
class IdTokenToken < Strategy
|
6
|
+
delegate :current_resource_owner, to: :server
|
7
|
+
|
8
|
+
def pre_auth
|
9
|
+
server.context.send(:pre_auth)
|
10
|
+
end
|
11
|
+
|
12
|
+
def request
|
13
|
+
@request ||= OAuth::IdTokenTokenRequest.new(pre_auth, current_resource_owner)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
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.
|
4
|
+
version: 1.3.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:
|
12
|
+
date: 2018-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: doorkeeper
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '4.
|
20
|
+
version: '4.3'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '4.
|
27
|
+
version: '4.3'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: json-jwt
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,6 +132,10 @@ files:
|
|
132
132
|
- bin/setup
|
133
133
|
- config/locales/en.yml
|
134
134
|
- doorkeeper-openid_connect.gemspec
|
135
|
+
- lib/doorkeeper/oauth/id_token_request.rb
|
136
|
+
- lib/doorkeeper/oauth/id_token_response.rb
|
137
|
+
- lib/doorkeeper/oauth/id_token_token_request.rb
|
138
|
+
- lib/doorkeeper/oauth/id_token_token_response.rb
|
135
139
|
- lib/doorkeeper/openid_connect.rb
|
136
140
|
- lib/doorkeeper/openid_connect/claims/aggregated_claim.rb
|
137
141
|
- lib/doorkeeper/openid_connect/claims/claim.rb
|
@@ -143,7 +147,9 @@ files:
|
|
143
147
|
- lib/doorkeeper/openid_connect/errors.rb
|
144
148
|
- lib/doorkeeper/openid_connect/helpers/controller.rb
|
145
149
|
- lib/doorkeeper/openid_connect/id_token.rb
|
150
|
+
- lib/doorkeeper/openid_connect/id_token_token.rb
|
146
151
|
- lib/doorkeeper/openid_connect/oauth/authorization/code.rb
|
152
|
+
- lib/doorkeeper/openid_connect/oauth/authorization/token.rb
|
147
153
|
- lib/doorkeeper/openid_connect/oauth/authorization_code_request.rb
|
148
154
|
- lib/doorkeeper/openid_connect/oauth/password_access_token_request.rb
|
149
155
|
- lib/doorkeeper/openid_connect/oauth/pre_authorization.rb
|
@@ -154,8 +160,11 @@ files:
|
|
154
160
|
- lib/doorkeeper/openid_connect/rails/routes.rb
|
155
161
|
- lib/doorkeeper/openid_connect/rails/routes/mapper.rb
|
156
162
|
- lib/doorkeeper/openid_connect/rails/routes/mapping.rb
|
163
|
+
- lib/doorkeeper/openid_connect/response_types_config.rb
|
157
164
|
- lib/doorkeeper/openid_connect/user_info.rb
|
158
165
|
- lib/doorkeeper/openid_connect/version.rb
|
166
|
+
- lib/doorkeeper/request/id_token.rb
|
167
|
+
- lib/doorkeeper/request/id_token_token.rb
|
159
168
|
- lib/generators/doorkeeper/openid_connect/install_generator.rb
|
160
169
|
- lib/generators/doorkeeper/openid_connect/migration_generator.rb
|
161
170
|
- lib/generators/doorkeeper/openid_connect/templates/initializer.rb
|