keycloak-api-rails 0.10.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +87 -87
- data/README.md +6 -6
- data/keycloak-api-rails.gemspec +2 -3
- data/lib/keycloak-api-rails.rb +7 -1
- data/lib/keycloak-api-rails/configuration.rb +1 -0
- data/lib/keycloak-api-rails/helper.rb +38 -8
- data/lib/keycloak-api-rails/http_client.rb +28 -0
- data/lib/keycloak-api-rails/middleware.rb +4 -1
- data/lib/keycloak-api-rails/public_key_cached_resolver.rb +4 -4
- data/lib/keycloak-api-rails/public_key_resolver.rb +5 -14
- data/lib/keycloak-api-rails/version.rb +1 -1
- metadata +7 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 054b6e617974528c6588167886f7ab5da9b60ed82cddcb6f2770d0d295e8e2c4
|
4
|
+
data.tar.gz: 12ab9f5071f0f85fa2c13cbe5732d851e6eff88a0f9866ad349ba30f27348a42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57ca553cd13c49a4202af7c7ed8949eccacd591dae317c0e65a953e4449e16eb7d95300c7f71b8e4f2f1bf5ba52df7b80c7a56619a033ff5a57d633a4cd5d56a
|
7
|
+
data.tar.gz: 40888d970c304133ea101c9e207f7aa378388ca602cf75313b75ac871910ba9cbd13a5755269f603dc60ccf4848143e1256de2dcb27c0a708718d3edf3b8f2ee
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [0.11.0] - 2019-11-21
|
9
|
+
|
10
|
+
* Remove dependency to `rest-client` (thanks to @@loicvigneron)
|
11
|
+
* Access Authorization Party from ENV (thanks to @@loicvigneron)
|
12
|
+
* New configuration option: `ca_certificate_file` (thanks to @@loicvigneron)
|
13
|
+
* Access the token from ENV
|
14
|
+
* Upgrade `json-jwt` to `1.11.0`
|
data/Gemfile.lock
CHANGED
@@ -1,127 +1,129 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
keycloak-api-rails (0.
|
5
|
-
json-jwt (>= 1.
|
4
|
+
keycloak-api-rails (0.11.0)
|
5
|
+
json-jwt (>= 1.11.0)
|
6
6
|
rails (>= 4.2)
|
7
|
-
rest-client (>= 2.0.2)
|
8
7
|
|
9
8
|
GEM
|
10
9
|
remote: https://rubygems.org/
|
11
10
|
specs:
|
12
|
-
actioncable (
|
13
|
-
actionpack (=
|
11
|
+
actioncable (6.0.1)
|
12
|
+
actionpack (= 6.0.1)
|
14
13
|
nio4r (~> 2.0)
|
15
14
|
websocket-driver (>= 0.6.1)
|
16
|
-
|
17
|
-
actionpack (=
|
18
|
-
|
19
|
-
|
15
|
+
actionmailbox (6.0.1)
|
16
|
+
actionpack (= 6.0.1)
|
17
|
+
activejob (= 6.0.1)
|
18
|
+
activerecord (= 6.0.1)
|
19
|
+
activestorage (= 6.0.1)
|
20
|
+
activesupport (= 6.0.1)
|
21
|
+
mail (>= 2.7.1)
|
22
|
+
actionmailer (6.0.1)
|
23
|
+
actionpack (= 6.0.1)
|
24
|
+
actionview (= 6.0.1)
|
25
|
+
activejob (= 6.0.1)
|
20
26
|
mail (~> 2.5, >= 2.5.4)
|
21
27
|
rails-dom-testing (~> 2.0)
|
22
|
-
actionpack (
|
23
|
-
actionview (=
|
24
|
-
activesupport (=
|
28
|
+
actionpack (6.0.1)
|
29
|
+
actionview (= 6.0.1)
|
30
|
+
activesupport (= 6.0.1)
|
25
31
|
rack (~> 2.0)
|
26
32
|
rack-test (>= 0.6.3)
|
27
33
|
rails-dom-testing (~> 2.0)
|
28
|
-
rails-html-sanitizer (~> 1.0, >= 1.0
|
29
|
-
|
30
|
-
|
34
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
35
|
+
actiontext (6.0.1)
|
36
|
+
actionpack (= 6.0.1)
|
37
|
+
activerecord (= 6.0.1)
|
38
|
+
activestorage (= 6.0.1)
|
39
|
+
activesupport (= 6.0.1)
|
40
|
+
nokogiri (>= 1.8.5)
|
41
|
+
actionview (6.0.1)
|
42
|
+
activesupport (= 6.0.1)
|
31
43
|
builder (~> 3.1)
|
32
44
|
erubi (~> 1.4)
|
33
45
|
rails-dom-testing (~> 2.0)
|
34
|
-
rails-html-sanitizer (~> 1.
|
35
|
-
activejob (
|
36
|
-
activesupport (=
|
46
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
47
|
+
activejob (6.0.1)
|
48
|
+
activesupport (= 6.0.1)
|
37
49
|
globalid (>= 0.3.6)
|
38
|
-
activemodel (
|
39
|
-
activesupport (=
|
40
|
-
activerecord (
|
41
|
-
activemodel (=
|
42
|
-
activesupport (=
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
activerecord (=
|
50
|
+
activemodel (6.0.1)
|
51
|
+
activesupport (= 6.0.1)
|
52
|
+
activerecord (6.0.1)
|
53
|
+
activemodel (= 6.0.1)
|
54
|
+
activesupport (= 6.0.1)
|
55
|
+
activestorage (6.0.1)
|
56
|
+
actionpack (= 6.0.1)
|
57
|
+
activejob (= 6.0.1)
|
58
|
+
activerecord (= 6.0.1)
|
47
59
|
marcel (~> 0.3.1)
|
48
|
-
activesupport (
|
60
|
+
activesupport (6.0.1)
|
49
61
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
50
62
|
i18n (>= 0.7, < 2)
|
51
63
|
minitest (~> 5.1)
|
52
64
|
tzinfo (~> 1.1)
|
65
|
+
zeitwerk (~> 2.2)
|
53
66
|
aes_key_wrap (1.0.1)
|
54
|
-
|
55
|
-
bindata (2.4.3)
|
67
|
+
bindata (2.4.4)
|
56
68
|
builder (3.2.3)
|
57
69
|
byebug (9.1.0)
|
58
|
-
concurrent-ruby (1.
|
59
|
-
crass (1.0.
|
70
|
+
concurrent-ruby (1.1.5)
|
71
|
+
crass (1.0.5)
|
60
72
|
diff-lcs (1.3)
|
61
|
-
|
62
|
-
|
63
|
-
erubi (1.7.1)
|
64
|
-
globalid (0.4.1)
|
73
|
+
erubi (1.9.0)
|
74
|
+
globalid (0.4.2)
|
65
75
|
activesupport (>= 4.2.0)
|
66
|
-
|
67
|
-
domain_name (~> 0.5)
|
68
|
-
i18n (1.1.0)
|
76
|
+
i18n (1.7.0)
|
69
77
|
concurrent-ruby (~> 1.0)
|
70
|
-
json-jwt (1.
|
71
|
-
activesupport
|
78
|
+
json-jwt (1.11.0)
|
79
|
+
activesupport (>= 4.2)
|
72
80
|
aes_key_wrap
|
73
81
|
bindata
|
74
|
-
loofah (2.
|
82
|
+
loofah (2.3.1)
|
75
83
|
crass (~> 1.0.2)
|
76
84
|
nokogiri (>= 1.5.9)
|
77
|
-
mail (2.7.
|
85
|
+
mail (2.7.1)
|
78
86
|
mini_mime (>= 0.1.1)
|
79
|
-
marcel (0.3.
|
87
|
+
marcel (0.3.3)
|
80
88
|
mimemagic (~> 0.3.2)
|
81
|
-
method_source (0.9.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
nio4r (2.3.1)
|
91
|
-
nokogiri (1.8.4)
|
92
|
-
mini_portile2 (~> 2.3.0)
|
93
|
-
rack (2.0.6)
|
89
|
+
method_source (0.9.2)
|
90
|
+
mimemagic (0.3.3)
|
91
|
+
mini_mime (1.0.2)
|
92
|
+
mini_portile2 (2.4.0)
|
93
|
+
minitest (5.13.0)
|
94
|
+
nio4r (2.5.2)
|
95
|
+
nokogiri (1.10.5)
|
96
|
+
mini_portile2 (~> 2.4.0)
|
97
|
+
rack (2.0.7)
|
94
98
|
rack-test (1.1.0)
|
95
99
|
rack (>= 1.0, < 3)
|
96
|
-
rails (
|
97
|
-
actioncable (=
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
100
|
+
rails (6.0.1)
|
101
|
+
actioncable (= 6.0.1)
|
102
|
+
actionmailbox (= 6.0.1)
|
103
|
+
actionmailer (= 6.0.1)
|
104
|
+
actionpack (= 6.0.1)
|
105
|
+
actiontext (= 6.0.1)
|
106
|
+
actionview (= 6.0.1)
|
107
|
+
activejob (= 6.0.1)
|
108
|
+
activemodel (= 6.0.1)
|
109
|
+
activerecord (= 6.0.1)
|
110
|
+
activestorage (= 6.0.1)
|
111
|
+
activesupport (= 6.0.1)
|
106
112
|
bundler (>= 1.3.0)
|
107
|
-
railties (=
|
113
|
+
railties (= 6.0.1)
|
108
114
|
sprockets-rails (>= 2.0.0)
|
109
115
|
rails-dom-testing (2.0.3)
|
110
116
|
activesupport (>= 4.2.0)
|
111
117
|
nokogiri (>= 1.6)
|
112
|
-
rails-html-sanitizer (1.0
|
113
|
-
loofah (~> 2.
|
114
|
-
railties (
|
115
|
-
actionpack (=
|
116
|
-
activesupport (=
|
118
|
+
rails-html-sanitizer (1.3.0)
|
119
|
+
loofah (~> 2.3)
|
120
|
+
railties (6.0.1)
|
121
|
+
actionpack (= 6.0.1)
|
122
|
+
activesupport (= 6.0.1)
|
117
123
|
method_source
|
118
124
|
rake (>= 0.8.7)
|
119
|
-
thor (>= 0.
|
120
|
-
rake (
|
121
|
-
rest-client (2.0.2)
|
122
|
-
http-cookie (>= 1.0.2, < 2.0)
|
123
|
-
mime-types (>= 1.16, < 4.0)
|
124
|
-
netrc (~> 0.8)
|
125
|
+
thor (>= 0.20.3, < 2.0)
|
126
|
+
rake (13.0.1)
|
125
127
|
rspec (3.7.0)
|
126
128
|
rspec-core (~> 3.7.0)
|
127
129
|
rspec-expectations (~> 3.7.0)
|
@@ -135,24 +137,22 @@ GEM
|
|
135
137
|
diff-lcs (>= 1.2.0, < 2.0)
|
136
138
|
rspec-support (~> 3.7.0)
|
137
139
|
rspec-support (3.7.0)
|
138
|
-
sprockets (
|
140
|
+
sprockets (4.0.0)
|
139
141
|
concurrent-ruby (~> 1.0)
|
140
142
|
rack (> 1, < 3)
|
141
143
|
sprockets-rails (3.2.1)
|
142
144
|
actionpack (>= 4.0)
|
143
145
|
activesupport (>= 4.0)
|
144
146
|
sprockets (>= 3.0.0)
|
145
|
-
thor (0.20.
|
147
|
+
thor (0.20.3)
|
146
148
|
thread_safe (0.3.6)
|
147
149
|
timecop (0.9.1)
|
148
150
|
tzinfo (1.2.5)
|
149
151
|
thread_safe (~> 0.1)
|
150
|
-
|
151
|
-
unf_ext
|
152
|
-
unf_ext (0.0.7.5)
|
153
|
-
websocket-driver (0.7.0)
|
152
|
+
websocket-driver (0.7.1)
|
154
153
|
websocket-extensions (>= 0.1.0)
|
155
|
-
websocket-extensions (0.1.
|
154
|
+
websocket-extensions (0.1.4)
|
155
|
+
zeitwerk (2.2.1)
|
156
156
|
|
157
157
|
PLATFORMS
|
158
158
|
ruby
|
@@ -164,4 +164,4 @@ DEPENDENCIES
|
|
164
164
|
timecop (= 0.9.1)
|
165
165
|
|
166
166
|
BUNDLED WITH
|
167
|
-
1.
|
167
|
+
1.17.3
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ This gem aims at validates Keycloak JWT token in Ruby On Rails APIs.
|
|
5
5
|
## Install
|
6
6
|
|
7
7
|
```ruby
|
8
|
-
gem "keycloak-api-rails", "0.
|
8
|
+
gem "keycloak-api-rails", "0.11.0"
|
9
9
|
```
|
10
10
|
|
11
11
|
## Token validation
|
@@ -14,7 +14,7 @@ Tokens send (through query strings or Authorization headers) to this Railtie Mid
|
|
14
14
|
|
15
15
|
## Pass token to the API
|
16
16
|
|
17
|
-
* Method 1: By adding an `Authorization` HTTP Header with its value set to `Bearer <your token>`.
|
17
|
+
* Method 1: By adding an `Authorization` HTTP Header with its value set to `Bearer <your token>`.
|
18
18
|
_e.g_ using curl: `curl -H "Authorization: Bearer <your-token>" https://api.pouet.io/api/more-pouets`
|
19
19
|
* Method 2: By providing the token via query string, especially via the parameter named `authorizationToken`. Keep in mind that this method is less secure (url are kept intact in your browser history, and so on...)
|
20
20
|
_e.g._ using curl: `curl https://api.pouet.io/api/more-pouets?authorizationToken<your-token>`
|
@@ -42,8 +42,8 @@ All options have a default value. However, all of them can be changed in your in
|
|
42
42
|
| `token_expiration_tolerance_in_seconds` | `10`| Logger | Optional | Number of seconds a token can expire before being rejected by the API. | `15` |
|
43
43
|
| `public_key_cache_ttl` | `86400`| Integer | Optional | Amount of time, in seconds, specifying maximum interval between two requests to {project_name} to retrieve new public keys. It is 86400 seconds (1 day) by default. At least once per this configured interval (1 day by default) will be new public key always downloaded. | `Rails.logger` |
|
44
44
|
| `custom_attributes` | `[]`| Array Of String | Optional | List of token attributes to read from each token and to add to their http request env | `["originalFirstName", "originalLastName"]` |
|
45
|
-
|
46
|
-
## Configure it
|
45
|
+
| `ca_certificate_file` | `nil`| String | Optional | Path to the certificate authority used to validate the Keycloak server certificate | `/credentials/production_root_ca_cert.pem` |
|
46
|
+
## Configure it
|
47
47
|
|
48
48
|
Create a `keycloak.rb` file in your Rails `config/initializers` folder. For instance:
|
49
49
|
|
@@ -65,7 +65,7 @@ Once this gem is configured in your Rails project, you can read, validate and us
|
|
65
65
|
|
66
66
|
### Keycloak Id
|
67
67
|
|
68
|
-
If you identify users using their Keycloak Id, this value can be read from your controllers using `Keycloak::Helper.current_user_id(request.env)`.
|
68
|
+
If you identify users using their Keycloak Id, this value can be read from your controllers using `Keycloak::Helper.current_user_id(request.env)`.
|
69
69
|
|
70
70
|
```ruby
|
71
71
|
class AuthenticatedController < ApplicationController
|
@@ -173,4 +173,4 @@ From the `keycloak-rails-api` directory:
|
|
173
173
|
|
174
174
|
## Next developments
|
175
175
|
|
176
|
-
*
|
176
|
+
* Manage multiple realms
|
data/keycloak-api-rails.gemspec
CHANGED
@@ -16,10 +16,9 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
18
|
spec.add_dependency "rails", ">= 4.2"
|
19
|
-
spec.add_dependency "json-jwt", ">= 1.
|
20
|
-
spec.add_dependency "rest-client", ">= 2.0.2"
|
19
|
+
spec.add_dependency "json-jwt", ">= 1.11.0"
|
21
20
|
|
22
21
|
spec.add_development_dependency "rspec", "3.7.0"
|
23
22
|
spec.add_development_dependency "timecop", "0.9.1"
|
24
23
|
spec.add_development_dependency "byebug", "9.1.0"
|
25
|
-
end
|
24
|
+
end
|
data/lib/keycloak-api-rails.rb
CHANGED
@@ -2,8 +2,10 @@ require "logger"
|
|
2
2
|
require "json/jwt"
|
3
3
|
require "uri"
|
4
4
|
require "date"
|
5
|
+
require "net/http"
|
5
6
|
|
6
7
|
require_relative "keycloak-api-rails/configuration"
|
8
|
+
require_relative "keycloak-api-rails/http_client"
|
7
9
|
require_relative "keycloak-api-rails/token_error"
|
8
10
|
require_relative "keycloak-api-rails/helper"
|
9
11
|
require_relative "keycloak-api-rails/public_key_resolver"
|
@@ -22,8 +24,12 @@ module Keycloak
|
|
22
24
|
@configuration
|
23
25
|
end
|
24
26
|
|
27
|
+
def self.http_client
|
28
|
+
@http_client ||= Keycloak::HTTPClient.new(config)
|
29
|
+
end
|
30
|
+
|
25
31
|
def self.public_key_resolver
|
26
|
-
@public_key_resolver ||= PublicKeyCachedResolver.from_configuration(config)
|
32
|
+
@public_key_resolver ||= PublicKeyCachedResolver.from_configuration(http_client, config)
|
27
33
|
end
|
28
34
|
|
29
35
|
def self.service
|
@@ -1,12 +1,15 @@
|
|
1
1
|
module Keycloak
|
2
2
|
class Helper
|
3
|
-
|
4
|
-
CURRENT_USER_ID_KEY
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
|
4
|
+
CURRENT_USER_ID_KEY = "keycloak:keycloak_id"
|
5
|
+
CURRENT_AUTHORIZED_PARTY_KEY = "keycloak:authorized_party"
|
6
|
+
CURRENT_USER_EMAIL_KEY = "keycloak:email"
|
7
|
+
CURRENT_USER_LOCALE_KEY = "keycloak:locale"
|
8
|
+
CURRENT_USER_ATTRIBUTES = "keycloak:attributes"
|
9
|
+
ROLES_KEY = "keycloak:roles"
|
10
|
+
RESOURCE_ROLES_KEY = "keycloak:resource_roles"
|
11
|
+
TOKEN_KEY = "keycloak:token"
|
12
|
+
QUERY_STRING_TOKEN_KEY = "authorizationToken"
|
10
13
|
|
11
14
|
def self.current_user_id(env)
|
12
15
|
env[CURRENT_USER_ID_KEY]
|
@@ -16,6 +19,22 @@ module Keycloak
|
|
16
19
|
env[CURRENT_USER_ID_KEY] = token["sub"]
|
17
20
|
end
|
18
21
|
|
22
|
+
def self.keycloak_token(env)
|
23
|
+
env[TOKEN_KEY]
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.assign_keycloak_token(env, token)
|
27
|
+
env[TOKEN_KEY] = token
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.current_authorized_party(env)
|
31
|
+
env[CURRENT_AUTHORIZED_PARTY_KEY]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.assign_current_authorized_party(env, token)
|
35
|
+
env[CURRENT_AUTHORIZED_PARTY_KEY] = token["azp"]
|
36
|
+
end
|
37
|
+
|
19
38
|
def self.current_user_email(env)
|
20
39
|
env[CURRENT_USER_EMAIL_KEY]
|
21
40
|
end
|
@@ -40,8 +59,19 @@ module Keycloak
|
|
40
59
|
env[ROLES_KEY] = token.dig("realm_access", "roles")
|
41
60
|
end
|
42
61
|
|
62
|
+
def self.current_resource_roles(env)
|
63
|
+
env[RESOURCE_ROLES_KEY]
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.assign_resource_roles(env, token)
|
67
|
+
env[RESOURCE_ROLES_KEY] = token.fetch("resource_access", {}).inject({}) do |resource_roles, (name, resource_attributes)|
|
68
|
+
resource_roles[name] = resource_attributes.fetch("roles", [])
|
69
|
+
resource_roles
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
43
73
|
def self.assign_current_user_custom_attributes(env, token, attribute_names)
|
44
|
-
env[CURRENT_USER_ATTRIBUTES] = token.select { |key,value| attribute_names.include?(key) }
|
74
|
+
env[CURRENT_USER_ATTRIBUTES] = token.select { |key, value| attribute_names.include?(key) }
|
45
75
|
end
|
46
76
|
|
47
77
|
def self.current_user_custom_attributes(env)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Keycloak
|
2
|
+
class HTTPClient
|
3
|
+
def initialize(configuration)
|
4
|
+
@server_url = configuration.server_url
|
5
|
+
@ca_certificate_file = configuration.ca_certificate_file
|
6
|
+
@x509_store = OpenSSL::X509::Store.new
|
7
|
+
@x509_store.set_default_paths
|
8
|
+
@x509_store.add_file(@ca_certificate_file) if @ca_certificate_file
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(realm_id, path)
|
12
|
+
uri = build_uri(realm_id, path)
|
13
|
+
use_ssl = uri.scheme == "http" ? false : true
|
14
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => use_ssl, :cert_store => @x509_store) do |http|
|
15
|
+
request = Net::HTTP::Get.new(uri)
|
16
|
+
response = http.request(request)
|
17
|
+
JSON.parse(response.body)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def build_uri(realm_id, path)
|
24
|
+
string_uri = File.join(@server_url, "realms", realm_id, path)
|
25
|
+
URI(string_uri)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -9,7 +9,7 @@ module Keycloak
|
|
9
9
|
method = env["REQUEST_METHOD"]
|
10
10
|
path = env["PATH_INFO"]
|
11
11
|
uri = env["REQUEST_URI"]
|
12
|
-
|
12
|
+
|
13
13
|
if service.need_authentication?(method, path, env)
|
14
14
|
logger.debug("Start authentication for #{method} : #{path}")
|
15
15
|
token = service.read_token(uri, env)
|
@@ -30,10 +30,13 @@ module Keycloak
|
|
30
30
|
|
31
31
|
def authentication_succeeded(env, decoded_token)
|
32
32
|
Helper.assign_current_user_id(env, decoded_token)
|
33
|
+
Helper.assign_current_authorized_party(env, decoded_token)
|
33
34
|
Helper.assign_current_user_email(env, decoded_token)
|
34
35
|
Helper.assign_current_user_locale(env, decoded_token)
|
35
36
|
Helper.assign_current_user_custom_attributes(env, decoded_token, config.custom_attributes)
|
36
37
|
Helper.assign_realm_roles(env, decoded_token)
|
38
|
+
Helper.assign_resource_roles(env, decoded_token)
|
39
|
+
Helper.assign_keycloak_token(env, decoded_token)
|
37
40
|
@app.call(env)
|
38
41
|
end
|
39
42
|
|
@@ -2,15 +2,15 @@ module Keycloak
|
|
2
2
|
class PublicKeyCachedResolver
|
3
3
|
attr_reader :cached_public_key_retrieved_at
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@resolver = PublicKeyResolver.new(
|
5
|
+
def initialize(http_client, realm_id, public_key_cache_ttl)
|
6
|
+
@resolver = PublicKeyResolver.new(http_client, realm_id)
|
7
7
|
@public_key_cache_ttl = public_key_cache_ttl
|
8
8
|
@cached_public_keys = nil
|
9
9
|
@cached_public_key_retrieved_at = nil
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.from_configuration(configuration)
|
13
|
-
PublicKeyCachedResolver.new(
|
12
|
+
def self.from_configuration(http_client, configuration)
|
13
|
+
PublicKeyCachedResolver.new(http_client, configuration.realm_id, configuration.public_key_cache_ttl)
|
14
14
|
end
|
15
15
|
|
16
16
|
def find_public_keys
|
@@ -1,21 +1,12 @@
|
|
1
1
|
module Keycloak
|
2
2
|
class PublicKeyResolver
|
3
|
-
def initialize(
|
4
|
-
@
|
3
|
+
def initialize(http_client, realm_id)
|
4
|
+
@realm_id = realm_id
|
5
|
+
@http_client = http_client
|
5
6
|
end
|
6
7
|
|
7
8
|
def find_public_keys
|
8
|
-
JSON::JWK::Set.new(
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def create_realm_url(server_url, realm_id)
|
14
|
-
"#{server_url}/realms/#{realm_id}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def create_public_certificate_url(server_url, realm_id)
|
18
|
-
"#{create_realm_url(server_url, realm_id)}/protocol/openid-connect/certs"
|
9
|
+
JSON::JWK::Set.new(@http_client.get(@realm_id, "protocol/openid-connect/certs")["keys"])
|
19
10
|
end
|
20
11
|
end
|
21
|
-
end
|
12
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keycloak-api-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorent Lempereur
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -30,28 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.11.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rest-client
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 2.0.2
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 2.0.2
|
40
|
+
version: 1.11.0
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rspec
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,6 +89,7 @@ extra_rdoc_files: []
|
|
103
89
|
files:
|
104
90
|
- ".gitignore"
|
105
91
|
- ".rspec"
|
92
|
+
- CHANGELOG.md
|
106
93
|
- Dockerfile
|
107
94
|
- Gemfile
|
108
95
|
- Gemfile.lock
|
@@ -112,6 +99,7 @@ files:
|
|
112
99
|
- lib/keycloak-api-rails.rb
|
113
100
|
- lib/keycloak-api-rails/configuration.rb
|
114
101
|
- lib/keycloak-api-rails/helper.rb
|
102
|
+
- lib/keycloak-api-rails/http_client.rb
|
115
103
|
- lib/keycloak-api-rails/middleware.rb
|
116
104
|
- lib/keycloak-api-rails/public_key_cached_resolver.rb
|
117
105
|
- lib/keycloak-api-rails/public_key_resolver.rb
|
@@ -145,8 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
133
|
- !ruby/object:Gem::Version
|
146
134
|
version: '0'
|
147
135
|
requirements: []
|
148
|
-
|
149
|
-
rubygems_version: 2.6.4
|
136
|
+
rubygems_version: 3.0.6
|
150
137
|
signing_key:
|
151
138
|
specification_version: 4
|
152
139
|
summary: Rails middleware that validates Authorization token emitted by Keycloak
|