keycloak-api-rails 0.11.2 → 0.12.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
  SHA256:
3
- metadata.gz: ff480abdc3a9317e66060416095339c0612ff902fec1200bf1178c7445bfad39
4
- data.tar.gz: 29d7cb681cb2b05d801ceac2634b6773278516413112500968cdfe5fe7cae76e
3
+ metadata.gz: d0e8e7c47df127347543955ffc2ed362dc9c2efb549bc970f0efdd519f8cfb1a
4
+ data.tar.gz: 5b77f9cf1171a36db3d80c6cd31e0df8f0acb00a58916e9b7a4fdcfdec331ecd
5
5
  SHA512:
6
- metadata.gz: 3bd3bac623390a4efe1cf24a80106c820e2b66c186350ddab00140ccab44f1a919117afb28a2bdcf02651cc1b780d0e9cfc4e75256d6083339e140bdd44669f6
7
- data.tar.gz: fdbc7a9b37f8d5efdf5c11ee9ca01075ccfe9bbfaf7d5babfda1653eef9557a275c34487569d4589c2f5902c8ff13a7877f5e6d55133b0e4a7b9b4bd4fb00a58
6
+ metadata.gz: 38edbedbe88b629c6c6728eda1b60670cd9dd6b03f6246c4bfd79bcc6fd3832922c504b91c15f4f4c7e86128e4d143800f5562292cf0f38877e73f0f39f4a8ff
7
+ data.tar.gz: d6e9d6ca5a7d5a531e09e7e2fe63d026bd53f088ceabbb2484e59ab36ac1aee234d949ac30c342f67a2784442dacfb1d502762f35999d977d8175189c19193fa
data/CHANGELOG.md CHANGED
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.12.0] - 2023-04-11
9
+
10
+ * Introduce Opt-in mode as an alternative configuration (thanks to @theSteveMitchell)
11
+
8
12
  ## [0.11.2] - 2022-03-30
9
13
 
10
14
  * Update `Gemfile.lock` to avoid wrong CVE detections. The version of Rails should always be specified by the parent project. This change has no functional impact.
@@ -16,8 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
20
 
17
21
  ## [0.11.0] - 2019-11-21
18
22
 
19
- * Remove dependency to `rest-client` (thanks to @@loicvigneron)
20
- * Access Authorization Party from ENV (thanks to @@loicvigneron)
21
- * New configuration option: `ca_certificate_file` (thanks to @@loicvigneron)
23
+ * Remove dependency to `rest-client` (thanks to @loicvigneron)
24
+ * Access Authorization Party from ENV (thanks to @loicvigneron)
25
+ * New configuration option: `ca_certificate_file` (thanks to @loicvigneron)
22
26
  * Access the token from ENV
23
27
  * Upgrade `json-jwt` to `1.11.0`
data/Dockerfile CHANGED
@@ -9,6 +9,6 @@ COPY Gemfile /usr/src/app/
9
9
  COPY Gemfile.lock /usr/src/app/
10
10
  COPY keycloak-api-rails.gemspec /usr/src/app/
11
11
  COPY lib/keycloak-api-rails/version.rb /usr/src/app/lib/keycloak-api-rails/
12
- # RUN bundle install
12
+ RUN bundle install
13
13
  COPY . /usr/src/app
14
- # RUN bundle install
14
+ RUN bundle install
data/Gemfile.lock CHANGED
@@ -1,188 +1,192 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keycloak-api-rails (0.11.2)
4
+ keycloak-api-rails (0.12.0)
5
5
  json-jwt (>= 1.11.0)
6
6
  rails (>= 4.2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (7.0.2.3)
12
- actionpack (= 7.0.2.3)
13
- activesupport (= 7.0.2.3)
11
+ actioncable (7.0.4.3)
12
+ actionpack (= 7.0.4.3)
13
+ activesupport (= 7.0.4.3)
14
14
  nio4r (~> 2.0)
15
15
  websocket-driver (>= 0.6.1)
16
- actionmailbox (7.0.2.3)
17
- actionpack (= 7.0.2.3)
18
- activejob (= 7.0.2.3)
19
- activerecord (= 7.0.2.3)
20
- activestorage (= 7.0.2.3)
21
- activesupport (= 7.0.2.3)
16
+ actionmailbox (7.0.4.3)
17
+ actionpack (= 7.0.4.3)
18
+ activejob (= 7.0.4.3)
19
+ activerecord (= 7.0.4.3)
20
+ activestorage (= 7.0.4.3)
21
+ activesupport (= 7.0.4.3)
22
22
  mail (>= 2.7.1)
23
23
  net-imap
24
24
  net-pop
25
25
  net-smtp
26
- actionmailer (7.0.2.3)
27
- actionpack (= 7.0.2.3)
28
- actionview (= 7.0.2.3)
29
- activejob (= 7.0.2.3)
30
- activesupport (= 7.0.2.3)
26
+ actionmailer (7.0.4.3)
27
+ actionpack (= 7.0.4.3)
28
+ actionview (= 7.0.4.3)
29
+ activejob (= 7.0.4.3)
30
+ activesupport (= 7.0.4.3)
31
31
  mail (~> 2.5, >= 2.5.4)
32
32
  net-imap
33
33
  net-pop
34
34
  net-smtp
35
35
  rails-dom-testing (~> 2.0)
36
- actionpack (7.0.2.3)
37
- actionview (= 7.0.2.3)
38
- activesupport (= 7.0.2.3)
36
+ actionpack (7.0.4.3)
37
+ actionview (= 7.0.4.3)
38
+ activesupport (= 7.0.4.3)
39
39
  rack (~> 2.0, >= 2.2.0)
40
40
  rack-test (>= 0.6.3)
41
41
  rails-dom-testing (~> 2.0)
42
42
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
43
- actiontext (7.0.2.3)
44
- actionpack (= 7.0.2.3)
45
- activerecord (= 7.0.2.3)
46
- activestorage (= 7.0.2.3)
47
- activesupport (= 7.0.2.3)
43
+ actiontext (7.0.4.3)
44
+ actionpack (= 7.0.4.3)
45
+ activerecord (= 7.0.4.3)
46
+ activestorage (= 7.0.4.3)
47
+ activesupport (= 7.0.4.3)
48
48
  globalid (>= 0.6.0)
49
49
  nokogiri (>= 1.8.5)
50
- actionview (7.0.2.3)
51
- activesupport (= 7.0.2.3)
50
+ actionview (7.0.4.3)
51
+ activesupport (= 7.0.4.3)
52
52
  builder (~> 3.1)
53
53
  erubi (~> 1.4)
54
54
  rails-dom-testing (~> 2.0)
55
55
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
56
- activejob (7.0.2.3)
57
- activesupport (= 7.0.2.3)
56
+ activejob (7.0.4.3)
57
+ activesupport (= 7.0.4.3)
58
58
  globalid (>= 0.3.6)
59
- activemodel (7.0.2.3)
60
- activesupport (= 7.0.2.3)
61
- activerecord (7.0.2.3)
62
- activemodel (= 7.0.2.3)
63
- activesupport (= 7.0.2.3)
64
- activestorage (7.0.2.3)
65
- actionpack (= 7.0.2.3)
66
- activejob (= 7.0.2.3)
67
- activerecord (= 7.0.2.3)
68
- activesupport (= 7.0.2.3)
59
+ activemodel (7.0.4.3)
60
+ activesupport (= 7.0.4.3)
61
+ activerecord (7.0.4.3)
62
+ activemodel (= 7.0.4.3)
63
+ activesupport (= 7.0.4.3)
64
+ activestorage (7.0.4.3)
65
+ actionpack (= 7.0.4.3)
66
+ activejob (= 7.0.4.3)
67
+ activerecord (= 7.0.4.3)
68
+ activesupport (= 7.0.4.3)
69
69
  marcel (~> 1.0)
70
70
  mini_mime (>= 1.1.0)
71
- activesupport (7.0.2.3)
71
+ activesupport (7.0.4.3)
72
72
  concurrent-ruby (~> 1.0, >= 1.0.2)
73
73
  i18n (>= 1.6, < 2)
74
74
  minitest (>= 5.1)
75
75
  tzinfo (~> 2.0)
76
76
  aes_key_wrap (1.1.0)
77
- bindata (2.4.10)
77
+ bindata (2.4.15)
78
78
  builder (3.2.4)
79
- byebug (9.1.0)
80
- concurrent-ruby (1.1.10)
79
+ byebug (11.1.3)
80
+ concurrent-ruby (1.2.2)
81
81
  crass (1.0.6)
82
+ date (3.3.3)
82
83
  diff-lcs (1.5.0)
83
- digest (3.1.0)
84
- erubi (1.10.0)
85
- globalid (1.0.0)
84
+ erubi (1.12.0)
85
+ faraday (2.7.4)
86
+ faraday-net_http (>= 2.0, < 3.1)
87
+ ruby2_keywords (>= 0.0.4)
88
+ faraday-follow_redirects (0.3.0)
89
+ faraday (>= 1, < 3)
90
+ faraday-net_http (3.0.2)
91
+ globalid (1.1.0)
86
92
  activesupport (>= 5.0)
87
- i18n (1.10.0)
93
+ i18n (1.12.0)
88
94
  concurrent-ruby (~> 1.0)
89
- io-wait (0.2.1)
90
- json-jwt (1.13.0)
95
+ json-jwt (1.16.3)
91
96
  activesupport (>= 4.2)
92
97
  aes_key_wrap
93
98
  bindata
94
- loofah (2.15.0)
99
+ faraday (~> 2.0)
100
+ faraday-follow_redirects
101
+ loofah (2.20.0)
95
102
  crass (~> 1.0.2)
96
103
  nokogiri (>= 1.5.9)
97
- mail (2.7.1)
104
+ mail (2.8.1)
98
105
  mini_mime (>= 0.1.1)
106
+ net-imap
107
+ net-pop
108
+ net-smtp
99
109
  marcel (1.0.2)
100
110
  method_source (1.0.0)
101
111
  mini_mime (1.1.2)
102
- mini_portile2 (2.8.0)
103
- minitest (5.15.0)
104
- net-imap (0.2.3)
105
- digest
112
+ mini_portile2 (2.8.1)
113
+ minitest (5.18.0)
114
+ net-imap (0.3.4)
115
+ date
106
116
  net-protocol
107
- strscan
108
- net-pop (0.1.1)
109
- digest
117
+ net-pop (0.1.2)
110
118
  net-protocol
119
+ net-protocol (0.2.1)
111
120
  timeout
112
- net-protocol (0.1.2)
113
- io-wait
114
- timeout
115
- net-smtp (0.3.1)
116
- digest
121
+ net-smtp (0.3.3)
117
122
  net-protocol
118
- timeout
119
- nio4r (2.5.8)
120
- nokogiri (1.13.3)
123
+ nio4r (2.5.9)
124
+ nokogiri (1.14.3)
121
125
  mini_portile2 (~> 2.8.0)
122
126
  racc (~> 1.4)
123
- racc (1.6.0)
124
- rack (2.2.3)
125
- rack-test (1.1.0)
126
- rack (>= 1.0, < 3)
127
- rails (7.0.2.3)
128
- actioncable (= 7.0.2.3)
129
- actionmailbox (= 7.0.2.3)
130
- actionmailer (= 7.0.2.3)
131
- actionpack (= 7.0.2.3)
132
- actiontext (= 7.0.2.3)
133
- actionview (= 7.0.2.3)
134
- activejob (= 7.0.2.3)
135
- activemodel (= 7.0.2.3)
136
- activerecord (= 7.0.2.3)
137
- activestorage (= 7.0.2.3)
138
- activesupport (= 7.0.2.3)
127
+ racc (1.6.2)
128
+ rack (2.2.6.4)
129
+ rack-test (2.1.0)
130
+ rack (>= 1.3)
131
+ rails (7.0.4.3)
132
+ actioncable (= 7.0.4.3)
133
+ actionmailbox (= 7.0.4.3)
134
+ actionmailer (= 7.0.4.3)
135
+ actionpack (= 7.0.4.3)
136
+ actiontext (= 7.0.4.3)
137
+ actionview (= 7.0.4.3)
138
+ activejob (= 7.0.4.3)
139
+ activemodel (= 7.0.4.3)
140
+ activerecord (= 7.0.4.3)
141
+ activestorage (= 7.0.4.3)
142
+ activesupport (= 7.0.4.3)
139
143
  bundler (>= 1.15.0)
140
- railties (= 7.0.2.3)
144
+ railties (= 7.0.4.3)
141
145
  rails-dom-testing (2.0.3)
142
146
  activesupport (>= 4.2.0)
143
147
  nokogiri (>= 1.6)
144
- rails-html-sanitizer (1.4.2)
145
- loofah (~> 2.3)
146
- railties (7.0.2.3)
147
- actionpack (= 7.0.2.3)
148
- activesupport (= 7.0.2.3)
148
+ rails-html-sanitizer (1.5.0)
149
+ loofah (~> 2.19, >= 2.19.1)
150
+ railties (7.0.4.3)
151
+ actionpack (= 7.0.4.3)
152
+ activesupport (= 7.0.4.3)
149
153
  method_source
150
154
  rake (>= 12.2)
151
155
  thor (~> 1.0)
152
156
  zeitwerk (~> 2.5)
153
157
  rake (13.0.6)
154
- rspec (3.7.0)
155
- rspec-core (~> 3.7.0)
156
- rspec-expectations (~> 3.7.0)
157
- rspec-mocks (~> 3.7.0)
158
- rspec-core (3.7.1)
159
- rspec-support (~> 3.7.0)
160
- rspec-expectations (3.7.0)
158
+ rspec (3.12.0)
159
+ rspec-core (~> 3.12.0)
160
+ rspec-expectations (~> 3.12.0)
161
+ rspec-mocks (~> 3.12.0)
162
+ rspec-core (3.12.1)
163
+ rspec-support (~> 3.12.0)
164
+ rspec-expectations (3.12.2)
161
165
  diff-lcs (>= 1.2.0, < 2.0)
162
- rspec-support (~> 3.7.0)
163
- rspec-mocks (3.7.0)
166
+ rspec-support (~> 3.12.0)
167
+ rspec-mocks (3.12.5)
164
168
  diff-lcs (>= 1.2.0, < 2.0)
165
- rspec-support (~> 3.7.0)
166
- rspec-support (3.7.1)
167
- strscan (3.0.1)
169
+ rspec-support (~> 3.12.0)
170
+ rspec-support (3.12.0)
171
+ ruby2_keywords (0.0.5)
168
172
  thor (1.2.1)
169
- timecop (0.9.1)
170
- timeout (0.2.0)
171
- tzinfo (2.0.4)
173
+ timecop (0.9.6)
174
+ timeout (0.3.2)
175
+ tzinfo (2.0.6)
172
176
  concurrent-ruby (~> 1.0)
173
177
  websocket-driver (0.7.5)
174
178
  websocket-extensions (>= 0.1.0)
175
179
  websocket-extensions (0.1.5)
176
- zeitwerk (2.5.4)
180
+ zeitwerk (2.6.7)
177
181
 
178
182
  PLATFORMS
179
183
  ruby
180
184
 
181
185
  DEPENDENCIES
182
- byebug (= 9.1.0)
186
+ byebug (= 11.1.3)
183
187
  keycloak-api-rails!
184
- rspec (= 3.7.0)
185
- timecop (= 0.9.1)
188
+ rspec (= 3.12.0)
189
+ timecop (= 0.9.6)
186
190
 
187
191
  BUNDLED WITH
188
192
  2.1.4
data/README.md CHANGED
@@ -1,16 +1,16 @@
1
1
  # Keycloak-Rails-Api
2
2
 
3
- This gem aims at validates Keycloak JWT token in Ruby On Rails APIs.
3
+ This gem validates Keycloak JWT token for Ruby On Rails APIs.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```ruby
8
- gem "keycloak-api-rails", "0.11.2"
8
+ gem "keycloak-api-rails", "0.12.0"
9
9
  ```
10
10
 
11
11
  ## Token validation
12
12
 
13
- Tokens send (through query strings or Authorization headers) to this Railtie Middleware are validated against a Keycloak public key. This public key is downloaded every day by default (this interval can be changed through `public_key_cache_ttl`).
13
+ Tokens sent (through query strings or Authorization headers) are validated against a Keycloak public key. This public key is downloaded every day by default (this interval can be changed through `public_key_cache_ttl`).
14
14
 
15
15
  ## Pass token to the API
16
16
 
@@ -21,6 +21,20 @@ Tokens send (through query strings or Authorization headers) to this Railtie Mid
21
21
 
22
22
  _If both method are used at the same time, The query string as a higher priority when reading given tokens._
23
23
 
24
+ ## Opt-in vs. Opt-out validation
25
+
26
+ By default, Keycloak-api-rails installs as a Rack Middleware. It processes all requests before any application logic. URIs/Paths can be excluded (opted-out) from this validation using the 'skip_paths' config option
27
+
28
+ Alternatively, it can be configured to `opt-in` to validation. In this case, no Rack middleware is used, and controllers can request (opt-in) by including the module `Keycloak::authentication` and calling `keycloak_authenticate`, for example in a `before_action`, like so:
29
+
30
+ ```ruby
31
+ class MyApiController < ActionController::Base
32
+ include Keycloak::Authentication
33
+
34
+ before_action :keycloak_authenticate
35
+ end
36
+ ```
37
+
24
38
  ## When a token is validated
25
39
 
26
40
  In Rails controller, the request `env` variables has two more properties:
@@ -39,6 +53,7 @@ All options have a default value. However, all of them can be changed in your in
39
53
  | `realm_id` | `nil`| String | Required | Realm's name (not id, actually) | `master` |
40
54
  | `logger` | `Logger.new(STDOUT)`| Logger | Optional | The logger used by `keycloak-api-rails` | `Rails.logger` | 
41
55
  | `skip_paths` | `{}`| Hash of methods and paths regexp | Optional | Paths whose the token must not be validatefd | `{ get: [/^\/health\/.+/] }`| 
56
+ | `opt_in` | `false` | Boolean | Optional | When true, All requests will be validated (excluding requests matching `skip_paths`). When false, validation must be explicitly requested | `true`
42
57
  | `token_expiration_tolerance_in_seconds` | `10`| Logger | Optional | Number of seconds a token can expire before being rejected by the API. | `15` | 
43
58
  | `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
59
  | `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"]` | 
@@ -59,6 +74,19 @@ Keycloak.configure do |config|
59
74
  end
60
75
  ```
61
76
 
77
+ Or using opt-in configuration:
78
+
79
+ ```ruby
80
+ Keycloak.configure do |config|
81
+ config.server_url = ENV["KEYCLOAK_SERVER_URL"]
82
+ config.realm_id = ENV["KEYCLOAK_REALM_ID"]
83
+ config.logger = Rails.logger
84
+ config.opt_in = true
85
+ end
86
+ ```
87
+
88
+ When using `opt-in` is true, `skip_paths` is not used.
89
+
62
90
  ## Use cases
63
91
 
64
92
  Once this gem is configured in your Rails project, you can read, validate and use tokens in your controllers.
@@ -77,6 +105,24 @@ class AuthenticatedController < ApplicationController
77
105
  end
78
106
  ```
79
107
 
108
+ Or if using opt-in mode, the controller can request validation conditionally:
109
+ ```ruby
110
+ class MostlyAuthenticatedController < ApplicationController
111
+ include Keycloak::Authentication
112
+
113
+ before_action :keycloak_authenticate, only: show
114
+
115
+ def show
116
+ keycloak_id = Keycloak::Helper.current_user_id(request.env)
117
+ User.active.find_by(keycloak_id: keycloak_id)
118
+ end
119
+
120
+ def index
121
+ # unauthenticated
122
+ end
123
+ end
124
+ ```
125
+
80
126
  ### Roles
81
127
 
82
128
  `Keycloak::Helper.current_user_roles` can be use against a Rails request to read user's roles.
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.add_dependency "rails", ">= 4.2"
19
19
  spec.add_dependency "json-jwt", ">= 1.11.0"
20
20
 
21
- spec.add_development_dependency "rspec", "3.7.0"
22
- spec.add_development_dependency "timecop", "0.9.1"
23
- spec.add_development_dependency "byebug", "9.1.0"
21
+ spec.add_development_dependency "rspec", "3.12.0"
22
+ spec.add_development_dependency "timecop", "0.9.6"
23
+ spec.add_development_dependency "byebug", "11.1.3"
24
24
  end
@@ -0,0 +1,57 @@
1
+ module Keycloak
2
+ module Authentication
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ if respond_to?(:helper_method)
7
+ helper_method :keycloak_authenticate
8
+ end
9
+ end
10
+
11
+ protected
12
+
13
+ def keycloak_authenticate
14
+
15
+ env = request.env
16
+ method = env["REQUEST_METHOD"]
17
+ path = env["PATH_INFO"]
18
+ uri = env["REQUEST_URI"]
19
+
20
+ logger.debug("Start authentication for #{method} : #{path}")
21
+ token = service.read_token(uri, env)
22
+ decoded_token = service.decode_and_verify(token)
23
+ authentication_succeeded(env, decoded_token)
24
+
25
+ rescue TokenError => e
26
+ authentication_failed(e.message)
27
+ end
28
+
29
+ def authentication_failed(message)
30
+ logger.info(message)
31
+ [401, {"Content-Type" => "application/json"}, [ { error: message }.to_json]]
32
+ end
33
+
34
+ def authentication_succeeded(env, decoded_token)
35
+ Helper.assign_current_user_id(env, decoded_token)
36
+ Helper.assign_current_authorized_party(env, decoded_token)
37
+ Helper.assign_current_user_email(env, decoded_token)
38
+ Helper.assign_current_user_locale(env, decoded_token)
39
+ Helper.assign_current_user_custom_attributes(env, decoded_token, config.custom_attributes)
40
+ Helper.assign_realm_roles(env, decoded_token)
41
+ Helper.assign_resource_roles(env, decoded_token)
42
+ Helper.assign_keycloak_token(env, decoded_token)
43
+ end
44
+
45
+ def service
46
+ Keycloak.service
47
+ end
48
+
49
+ def logger
50
+ Keycloak.logger
51
+ end
52
+
53
+ def config
54
+ Keycloak.config
55
+ end
56
+ end
57
+ end
@@ -4,6 +4,7 @@ module Keycloak
4
4
  config_accessor :server_url
5
5
  config_accessor :realm_id
6
6
  config_accessor :skip_paths
7
+ config_accessor :opt_in
7
8
  config_accessor :token_expiration_tolerance_in_seconds
8
9
  config_accessor :public_key_cache_ttl
9
10
  config_accessor :custom_attributes
@@ -10,7 +10,7 @@ module Keycloak
10
10
  path = env["PATH_INFO"]
11
11
  uri = env["REQUEST_URI"]
12
12
 
13
- if service.need_authentication?(method, path, env)
13
+ if service.need_middleware_authentication?(method, path, env)
14
14
  logger.debug("Start authentication for #{method} : #{path}")
15
15
  token = service.read_token(uri, env)
16
16
  decoded_token = service.decode_and_verify(token)
@@ -4,6 +4,7 @@ module Keycloak
4
4
  def initialize(key_resolver)
5
5
  @key_resolver = key_resolver
6
6
  @skip_paths = Keycloak.config.skip_paths
7
+ @opt_in = Keycloak.config.opt_in
7
8
  @logger = Keycloak.config.logger
8
9
  @token_expiration_tolerance_in_seconds = Keycloak.config.token_expiration_tolerance_in_seconds
9
10
  end
@@ -34,8 +35,8 @@ module Keycloak
34
35
  Helper.read_token_from_query_string(uri) || Helper.read_token_from_headers(headers)
35
36
  end
36
37
 
37
- def need_authentication?(method, path, headers)
38
- !should_skip?(method, path) && !is_preflight?(method, headers)
38
+ def need_middleware_authentication?(method, path, headers)
39
+ !is_preflight?(method, headers) && (!@opt_in && !should_skip?(method, path))
39
40
  end
40
41
 
41
42
  private
@@ -1,3 +1,3 @@
1
1
  module Keycloak
2
- VERSION = "0.11.2"
2
+ VERSION = "0.12.0"
3
3
  end
@@ -4,6 +4,7 @@ require "uri"
4
4
  require "date"
5
5
  require "net/http"
6
6
 
7
+ require_relative "keycloak-api-rails/authentication"
7
8
  require_relative "keycloak-api-rails/configuration"
8
9
  require_relative "keycloak-api-rails/http_client"
9
10
  require_relative "keycloak-api-rails/token_error"
@@ -46,6 +47,7 @@ module Keycloak
46
47
  config.realm_id = nil
47
48
  config.logger = ::Logger.new(STDOUT)
48
49
  config.skip_paths = {}
50
+ config.opt_in = false
49
51
  config.token_expiration_tolerance_in_seconds = 10
50
52
  config.public_key_cache_ttl = 86400
51
53
  config.custom_attributes = []
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe Keycloak::Authentication do
4
+ class ExampleController < ActionController::Base
5
+ include Keycloak::Authentication
6
+ # Mark protected methods public so they may be called in tests
7
+ public(*Keycloak::Authentication.protected_instance_methods)
8
+ end
9
+
10
+ let(:controller) { ExampleController.new }
11
+ let(:token) { 'keycloak_valid_token'}
12
+ let(:headers) do
13
+ {
14
+ 'REQUEST_METHOD' => :get,
15
+ 'REQUEST_URI' => 'http://www.an-url.io',
16
+ 'HTTP_AUTHORIZATION' => "Bearer #{token}"
17
+ }
18
+ end
19
+
20
+ describe "#keycloak_authenticate" do
21
+ before do
22
+ # Mock request object because we aren't using real request spec
23
+ allow(controller).to receive(:request).and_return(double("request", env: headers ))
24
+ end
25
+
26
+ it "it authenticates with request header" do
27
+ expect_any_instance_of(Keycloak::Service).to receive(:decode_and_verify).with(token).and_return("A User")
28
+ expect(controller).to receive(:authentication_succeeded)
29
+ controller.keycloak_authenticate
30
+ end
31
+ end
32
+ end
@@ -103,7 +103,7 @@ RSpec.describe Keycloak::Service do
103
103
  end
104
104
  end
105
105
 
106
- describe "#need_authentication?" do
106
+ describe "#need_middleware_authentication?" do
107
107
 
108
108
  let(:method) { nil }
109
109
  let(:path) { nil }
@@ -115,7 +115,7 @@ RSpec.describe Keycloak::Service do
115
115
  post: [/^\/skip/],
116
116
  get: [/^\/skip/]
117
117
  }
118
- @result = service.need_authentication?(method, path, headers)
118
+ @result = service.need_middleware_authentication?(method, path, headers)
119
119
  end
120
120
 
121
121
  context "when method is nil" do
@@ -175,6 +175,18 @@ RSpec.describe Keycloak::Service do
175
175
  expect(@result).to be false
176
176
  end
177
177
  end
178
+
179
+ context "when configured as opt_in" do
180
+ before do
181
+ Keycloak.config.opt_in = true
182
+ service2 = Keycloak::Service.new(key_resolver)
183
+ @result = service2.need_middleware_authentication?(method, path, headers)
184
+ end
185
+
186
+ it "should return false" do
187
+ expect(@result).to be false
188
+ end
189
+ end
178
190
  end
179
191
 
180
192
  describe "#read_token" do
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.11.2
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorent Lempereur
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-30 00:00:00.000000000 Z
11
+ date: 2023-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -44,42 +44,42 @@ dependencies:
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 3.7.0
47
+ version: 3.12.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 3.7.0
54
+ version: 3.12.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: timecop
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.9.1
61
+ version: 0.9.6
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.9.1
68
+ version: 0.9.6
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: byebug
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 9.1.0
75
+ version: 11.1.3
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 9.1.0
82
+ version: 11.1.3
83
83
  description: Rails middleware that validates Authorization token emitted by Keycloak
84
84
  email:
85
85
  - lorent.lempereur.dev@gmail.com
@@ -97,6 +97,7 @@ files:
97
97
  - README.md
98
98
  - keycloak-api-rails.gemspec
99
99
  - lib/keycloak-api-rails.rb
100
+ - lib/keycloak-api-rails/authentication.rb
100
101
  - lib/keycloak-api-rails/configuration.rb
101
102
  - lib/keycloak-api-rails/helper.rb
102
103
  - lib/keycloak-api-rails/http_client.rb
@@ -107,6 +108,7 @@ files:
107
108
  - lib/keycloak-api-rails/service.rb
108
109
  - lib/keycloak-api-rails/token_error.rb
109
110
  - lib/keycloak-api-rails/version.rb
111
+ - spec/keycloak-api-rails/authentication_spec.rb
110
112
  - spec/keycloak-api-rails/helper_spec.rb
111
113
  - spec/keycloak-api-rails/public_key_cached_resolver_spec.rb
112
114
  - spec/keycloak-api-rails/service_spec.rb
@@ -118,7 +120,7 @@ homepage: https://github.com/looorent/keycloak-api-rails
118
120
  licenses:
119
121
  - MIT
120
122
  metadata: {}
121
- post_install_message:
123
+ post_install_message:
122
124
  rdoc_options: []
123
125
  require_paths:
124
126
  - lib
@@ -133,8 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
135
  - !ruby/object:Gem::Version
134
136
  version: '0'
135
137
  requirements: []
136
- rubygems_version: 3.2.3
137
- signing_key:
138
+ rubygems_version: 3.0.3.1
139
+ signing_key:
138
140
  specification_version: 4
139
141
  summary: Rails middleware that validates Authorization token emitted by Keycloak
140
142
  test_files: []