omniauth-keycloak 1.2.0 → 1.4.4

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: 6f523d3b03c2258b9b49ca70dd94a02e9104de24a6148ee2d0018c9d3301ffe0
4
- data.tar.gz: 820eaba1eb35fce32c80a82293ab58ba1c154e307b191cce0b6a37b5888412d0
3
+ metadata.gz: 79b854153d87dedf293c8d1e4d30994169a92633d69ef4848e1a1af0356a82c2
4
+ data.tar.gz: 54f9007dd675375cec26c5b2c5447bc85b5077fa378723c099243501794eedb9
5
5
  SHA512:
6
- metadata.gz: de576c60d232f49150b0923ec1496c1e6ffdfafdb0fa3a85e3aa17d08952faacfd955a66d292dff352740965599720e645d3866b9d39f364d141bf686445a115
7
- data.tar.gz: cdf8238793033678b6a348b11111d95ea5449b61d50a63fc1b109e302d4a2616fb0e979acbdef33e5709dd0c0eee6481c9225bba57f7dbaae4a9b42688478535
6
+ metadata.gz: 1b0f823afd6af3f57472078f79da245b14867cfff35b1e892c777d1cdfe779524e6e68877534fdc19fc8b372705b777bf350d649a91f6b0bd7b8e7fd020b97ca
7
+ data.tar.gz: 8f51a1218d726e2a3de85d01355297ade8fe6e6f705752c870e374bf18684bdbf5bb2e83294e3653bf7ecc0885ce52383eec81f6dc37734b05bdf910732ddb00
data/CHANGELOG.md ADDED
@@ -0,0 +1,103 @@
1
+ # Changelog
2
+
3
+ ## [v1.4.3](https://github.com/ccrockett/omniauth-keycloak/tree/v1.4.3) (2022-07-24)
4
+
5
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.4.2...v1.4.3)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Error: uninitialized constant OmniAuth::Strategies::KeycloakOpenId::MultiJson after gem update [\#30](https://github.com/ccrockett/omniauth-keycloak/issues/30)
10
+
11
+ ## [v1.4.2](https://github.com/ccrockett/omniauth-keycloak/tree/v1.4.2) (2022-06-14)
12
+
13
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.4.1...v1.4.2)
14
+
15
+ **Closed issues:**
16
+
17
+ - Adjust endpoints to updated Keycloak paths [\#29](https://github.com/ccrockett/omniauth-keycloak/issues/29)
18
+ - Expose id\_token inside extra hash of auth hash [\#25](https://github.com/ccrockett/omniauth-keycloak/issues/25)
19
+
20
+ **Merged pull requests:**
21
+
22
+ - Set omniauth version to \>= 2.0 [\#28](https://github.com/ccrockett/omniauth-keycloak/pull/28) ([hobbypunk90](https://github.com/hobbypunk90))
23
+
24
+ ## [v1.4.1](https://github.com/ccrockett/omniauth-keycloak/tree/v1.4.1) (2022-05-25)
25
+
26
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.4.0...v1.4.1)
27
+
28
+ **Closed issues:**
29
+
30
+ - Get Request is now Post Request [\#23](https://github.com/ccrockett/omniauth-keycloak/issues/23)
31
+ - Is the "/auth/" part mandatory in Keycloak's configuration URL? [\#19](https://github.com/ccrockett/omniauth-keycloak/issues/19)
32
+ - Add example instructions for Keycloak configuration [\#14](https://github.com/ccrockett/omniauth-keycloak/issues/14)
33
+
34
+ **Merged pull requests:**
35
+
36
+ - expose id\_token inside extra hash of auth hash [\#26](https://github.com/ccrockett/omniauth-keycloak/pull/26) ([rah-wtag](https://github.com/rah-wtag))
37
+ - Bump bindata from 2.4.9 to 2.4.10 [\#22](https://github.com/ccrockett/omniauth-keycloak/pull/22) ([dependabot[bot]](https://github.com/apps/dependabot))
38
+
39
+ ## [v1.4.0](https://github.com/ccrockett/omniauth-keycloak/tree/v1.4.0) (2021-12-18)
40
+
41
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.3.0...v1.4.0)
42
+
43
+ **Closed issues:**
44
+
45
+ - Are there any reason to specify one certificate key to decode JWT? [\#17](https://github.com/ccrockett/omniauth-keycloak/issues/17)
46
+ - No route matches \[POST\] "/auth/keycloak\_openid" [\#15](https://github.com/ccrockett/omniauth-keycloak/issues/15)
47
+
48
+ **Merged pull requests:**
49
+
50
+ - Use JSON::JWK::Set instead of JSON::JWK [\#21](https://github.com/ccrockett/omniauth-keycloak/pull/21) ([hobbypunk90](https://github.com/hobbypunk90))
51
+ - Allow pass a Proc to the setup option when you specify a strategy [\#18](https://github.com/ccrockett/omniauth-keycloak/pull/18) ([Cambero](https://github.com/Cambero))
52
+ - Add information on how to use it to readme [\#16](https://github.com/ccrockett/omniauth-keycloak/pull/16) ([frenesim](https://github.com/frenesim))
53
+
54
+ ## [v1.3.0](https://github.com/ccrockett/omniauth-keycloak/tree/v1.3.0) (2021-05-17)
55
+
56
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.2.1...v1.3.0)
57
+
58
+ **Merged pull requests:**
59
+
60
+ - Bump Omniauth dependencies to v2 [\#13](https://github.com/ccrockett/omniauth-keycloak/pull/13) ([offner](https://github.com/offner))
61
+
62
+ ## [v1.2.1](https://github.com/ccrockett/omniauth-keycloak/tree/v1.2.1) (2020-12-19)
63
+
64
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.2.0...v1.2.1)
65
+
66
+ **Closed issues:**
67
+
68
+ - Dynamically load Client and Realm [\#11](https://github.com/ccrockett/omniauth-keycloak/issues/11)
69
+ - cannot load such file -- /Library/Ruby/Gems/2.6.0/gems/omniauth-keycloak-1.2.0/lib/omniauth-keycloak.rb \(LoadError\) [\#8](https://github.com/ccrockett/omniauth-keycloak/issues/8)
70
+ - Release json-jwt version restriction change [\#5](https://github.com/ccrockett/omniauth-keycloak/issues/5)
71
+
72
+ **Merged pull requests:**
73
+
74
+ - Raise errors on setup failure and logging with OmniAuth::Strategy::log method [\#10](https://github.com/ccrockett/omniauth-keycloak/pull/10) ([alexpetrov](https://github.com/alexpetrov))
75
+ - Bump json from 2.1.0 to 2.3.1 [\#9](https://github.com/ccrockett/omniauth-keycloak/pull/9) ([dependabot[bot]](https://github.com/apps/dependabot))
76
+ - Bump rack from 2.2.2 to 2.2.3 [\#7](https://github.com/ccrockett/omniauth-keycloak/pull/7) ([dependabot[bot]](https://github.com/apps/dependabot))
77
+
78
+ ## [v1.2.0](https://github.com/ccrockett/omniauth-keycloak/tree/v1.2.0) (2020-05-28)
79
+
80
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.1.0...v1.2.0)
81
+
82
+ **Merged pull requests:**
83
+
84
+ - Bump activesupport from 6.0.1 to 6.0.3.1 [\#6](https://github.com/ccrockett/omniauth-keycloak/pull/6) ([dependabot[bot]](https://github.com/apps/dependabot))
85
+ - Update rake requirement from ~\> 10.0 to ~\> 13.0 [\#4](https://github.com/ccrockett/omniauth-keycloak/pull/4) ([dependabot[bot]](https://github.com/apps/dependabot))
86
+ - Bump rack from 2.0.7 to 2.0.8 [\#2](https://github.com/ccrockett/omniauth-keycloak/pull/2) ([dependabot[bot]](https://github.com/apps/dependabot))
87
+ - Adding Devise Documentation [\#1](https://github.com/ccrockett/omniauth-keycloak/pull/1) ([masonhensley](https://github.com/masonhensley))
88
+
89
+ ## [v1.1.0](https://github.com/ccrockett/omniauth-keycloak/tree/v1.1.0) (2018-12-16)
90
+
91
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.0.1...v1.1.0)
92
+
93
+ ## [v1.0.1](https://github.com/ccrockett/omniauth-keycloak/tree/v1.0.1) (2018-12-16)
94
+
95
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/v1.0.0...v1.0.1)
96
+
97
+ ## [v1.0.0](https://github.com/ccrockett/omniauth-keycloak/tree/v1.0.0) (2018-12-16)
98
+
99
+ [Full Changelog](https://github.com/ccrockett/omniauth-keycloak/compare/7877c8a75f9e3f342b49bf808fa69965377d60b5...v1.0.0)
100
+
101
+
102
+
103
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/Gemfile.lock CHANGED
@@ -1,98 +1,101 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- omniauth-keycloak (1.2.0)
5
- json-jwt (~> 1.12)
6
- omniauth (~> 1.9.0)
7
- omniauth-oauth2 (~> 1.6.0)
4
+ omniauth-keycloak (1.4.2)
5
+ faraday
6
+ json-jwt (~> 1.13.0)
7
+ omniauth (>= 2.0)
8
+ omniauth-oauth2 (~> 1.7.1)
8
9
 
9
10
  GEM
10
11
  remote: https://rubygems.org/
11
12
  specs:
12
- activesupport (6.0.3.1)
13
+ activesupport (7.0.3)
13
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
- i18n (>= 0.7, < 2)
15
- minitest (~> 5.1)
16
- tzinfo (~> 1.1)
17
- zeitwerk (~> 2.2, >= 2.2.2)
18
- addressable (2.5.2)
19
- public_suffix (>= 2.0.2, < 4.0)
20
- aes_key_wrap (1.0.1)
21
- bindata (2.4.7)
22
- concurrent-ruby (1.1.6)
23
- crack (0.4.3)
24
- safe_yaml (~> 1.0.0)
25
- diff-lcs (1.3)
26
- docile (1.3.1)
27
- faraday (1.0.1)
28
- multipart-post (>= 1.2, < 3)
29
- hashdiff (0.3.7)
30
- hashie (4.1.0)
31
- i18n (1.8.2)
15
+ i18n (>= 1.6, < 2)
16
+ minitest (>= 5.1)
17
+ tzinfo (~> 2.0)
18
+ addressable (2.8.0)
19
+ public_suffix (>= 2.0.2, < 5.0)
20
+ aes_key_wrap (1.1.0)
21
+ bindata (2.4.10)
22
+ concurrent-ruby (1.1.10)
23
+ crack (0.4.5)
24
+ rexml
25
+ diff-lcs (1.4.4)
26
+ docile (1.4.0)
27
+ faraday (2.3.0)
28
+ faraday-net_http (~> 2.0)
29
+ ruby2_keywords (>= 0.0.4)
30
+ faraday-net_http (2.0.3)
31
+ hashdiff (1.0.1)
32
+ hashie (5.0.0)
33
+ i18n (1.10.0)
32
34
  concurrent-ruby (~> 1.0)
33
- json (2.1.0)
34
- json-jwt (1.12.0)
35
+ json-jwt (1.13.0)
35
36
  activesupport (>= 4.2)
36
37
  aes_key_wrap
37
38
  bindata
38
- jwt (2.2.1)
39
- minitest (5.14.1)
40
- multi_json (1.14.1)
39
+ jwt (2.3.0)
40
+ minitest (5.15.0)
41
+ multi_json (1.15.0)
41
42
  multi_xml (0.6.0)
42
- multipart-post (2.1.1)
43
- oauth2 (1.4.4)
44
- faraday (>= 0.8, < 2.0)
43
+ oauth2 (1.4.9)
44
+ faraday (>= 0.17.3, < 3.0)
45
45
  jwt (>= 1.0, < 3.0)
46
46
  multi_json (~> 1.3)
47
47
  multi_xml (~> 0.5)
48
48
  rack (>= 1.2, < 3)
49
- omniauth (1.9.1)
49
+ omniauth (2.0.4)
50
50
  hashie (>= 3.4.6)
51
51
  rack (>= 1.6.2, < 3)
52
- omniauth-oauth2 (1.6.0)
53
- oauth2 (~> 1.1)
54
- omniauth (~> 1.9)
55
- public_suffix (3.0.3)
56
- rack (2.2.2)
52
+ rack-protection
53
+ omniauth-oauth2 (1.7.2)
54
+ oauth2 (~> 1.4)
55
+ omniauth (>= 1.9, < 3)
56
+ public_suffix (4.0.6)
57
+ rack (2.2.3)
58
+ rack-protection (2.2.0)
59
+ rack
57
60
  rake (13.0.1)
58
- rspec (3.8.0)
59
- rspec-core (~> 3.8.0)
60
- rspec-expectations (~> 3.8.0)
61
- rspec-mocks (~> 3.8.0)
62
- rspec-core (3.8.0)
63
- rspec-support (~> 3.8.0)
64
- rspec-expectations (3.8.1)
61
+ rexml (3.2.5)
62
+ rspec (3.10.0)
63
+ rspec-core (~> 3.10.0)
64
+ rspec-expectations (~> 3.10.0)
65
+ rspec-mocks (~> 3.10.0)
66
+ rspec-core (3.10.1)
67
+ rspec-support (~> 3.10.0)
68
+ rspec-expectations (3.10.1)
65
69
  diff-lcs (>= 1.2.0, < 2.0)
66
- rspec-support (~> 3.8.0)
67
- rspec-mocks (3.8.0)
70
+ rspec-support (~> 3.10.0)
71
+ rspec-mocks (3.10.2)
68
72
  diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.8.0)
70
- rspec-support (3.8.0)
71
- safe_yaml (1.0.4)
72
- simplecov (0.16.1)
73
+ rspec-support (~> 3.10.0)
74
+ rspec-support (3.10.3)
75
+ ruby2_keywords (0.0.5)
76
+ simplecov (0.21.2)
73
77
  docile (~> 1.1)
74
- json (>= 1.8, < 3)
75
- simplecov-html (~> 0.10.0)
76
- simplecov-html (0.10.2)
77
- thread_safe (0.3.6)
78
- tzinfo (1.2.7)
79
- thread_safe (~> 0.1)
80
- webmock (3.4.2)
81
- addressable (>= 2.3.6)
78
+ simplecov-html (~> 0.11)
79
+ simplecov_json_formatter (~> 0.1)
80
+ simplecov-html (0.12.3)
81
+ simplecov_json_formatter (0.1.3)
82
+ tzinfo (2.0.4)
83
+ concurrent-ruby (~> 1.0)
84
+ webmock (3.14.0)
85
+ addressable (>= 2.8.0)
82
86
  crack (>= 0.3.2)
83
- hashdiff
84
- zeitwerk (2.3.0)
87
+ hashdiff (>= 0.4.0, < 2.0.0)
85
88
 
86
89
  PLATFORMS
87
90
  ruby
88
91
 
89
92
  DEPENDENCIES
90
- bundler (~> 1.16)
93
+ bundler (~> 2.2)
91
94
  omniauth-keycloak!
92
95
  rake (~> 13.0)
93
- rspec (~> 3.0)
94
- simplecov (~> 0.16.1)
95
- webmock (~> 3.4.2)
96
+ rspec (~> 3.10)
97
+ simplecov (~> 0.21)
98
+ webmock (~> 3.14)
96
99
 
97
100
  BUNDLED WITH
98
- 2.1.4
101
+ 2.2.31
data/README.md CHANGED
@@ -16,6 +16,15 @@ Or install it yourself as:
16
16
 
17
17
  $ gem install omniauth-keycloak
18
18
 
19
+ ## Use with Keycloak >= 17 (Quarkus distribution)
20
+ In version 17 of Keycloak, `/auth` was removed from the default context path. (See Issue [#29](https://github.com/ccrockett/omniauth-keycloak/issues/29))
21
+ In order to reduce breaking existing user's setup, this gem assumes `/auth` as the default context.
22
+ __So if you want to use Keycloak 17 or greater then you must do one of the following:__
23
+
24
+ 1. Pass in `--http-relative-path '/auth'` option with the keycloak start command
25
+ 2. Pass in a empty string for you base_url client_option:
26
+ `client_options: {base_url: '', site: 'https://example.keycloak-url.com', realm: 'example-realm'}`
27
+
19
28
  ## Usage
20
29
 
21
30
  `OmniAuth::Strategies::Keycloak` is simply a Rack middleware. Read the OmniAuth docs for detailed instructions: https://github.com/intridea/omniauth.
@@ -25,10 +34,33 @@ Here's a quick example, adding the middleware to a Rails app in `config/initiali
25
34
  ```ruby
26
35
  Rails.application.config.middleware.use OmniAuth::Builder do
27
36
  provider :keycloak_openid, 'Example-Client', '19cca35f-dddd-473a-bdd5-03f00d61d884',
28
- client_options: {site: 'https://example.keycloak-url.com', realm: 'example-realm'}
37
+ client_options: {site: 'https://example.keycloak-url.com', realm: 'example-realm'},
38
+ name: 'keycloak'
39
+ end
40
+ ```
41
+ This will allow a POST request to `auth/keycloak` since the name is set to keycloak
42
+
43
+ Or using a proc setup with a custom options:
44
+
45
+ ```ruby
46
+ Rails.application.config.middleware.use OmniAuth::Builder do
47
+ SETUP_PROC = lambda do |env|
48
+ request = Rack::Request.new(env)
49
+ organization = Organization.find_by(host: request.host)
50
+ provider_config = organization.enabled_omniauth_providers[:keycloakopenid]
51
+
52
+ env["omniauth.strategy"].options[:client_id] = provider_config[:client_id]
53
+ env["omniauth.strategy"].options[:client_secret] = provider_config[:client_secret]
54
+ env["omniauth.strategy"].options[:client_options] = { site: provider_config[:site], realm: provider_config[:realm] }
55
+ end
56
+
57
+ Rails.application.config.middleware.use OmniAuth::Builder do
58
+ provider :keycloak_openid, setup: SETUP_PROC
59
+ end
29
60
  end
30
61
  ```
31
62
 
63
+
32
64
  ## Devise Usage
33
65
  Adapted from [Devise OmniAuth Instructions](https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview)
34
66
 
@@ -43,7 +75,7 @@ end
43
75
  # config/initializers/devise.rb
44
76
  config.omniauth :keycloak_openid, "Example-Client-Name", "example-secret-if-configured", client_options: { site: "https://example.keycloak-url.com", realm: "example-realm" }, :strategy_class => OmniAuth::Strategies::KeycloakOpenId
45
77
 
46
- # Below controller assumes callback route configuration following
78
+ # Below controller assumes callback route configuration following
47
79
  # in config/routes.rb
48
80
  Devise.setup do |config|
49
81
  # ...
@@ -70,6 +102,17 @@ end
70
102
 
71
103
  ```
72
104
 
105
+ ## Configuration
106
+ * __Base Url other than /auth__
107
+ This gem tries to get the keycloak configuration from `"#{site}/auth/realms/#{realm}/.well-known/openid-configuration"`. If your keycloak server has been setup to use a different "root" url other than `/auth` then you need to pass in the `base_url` option when setting up the gem:
108
+ ```ruby
109
+ Rails.application.config.middleware.use OmniAuth::Builder do
110
+ provider :keycloak_openid, 'Example-Client', '19cca35f-dddd-473a-bdd5-03f00d61d884',
111
+ client_options: {site: 'https://example.keycloak-url.com', realm: 'example-realm', base_url: '/authorize'},
112
+ name: 'keycloak'
113
+ end
114
+ ```
115
+
73
116
  ## Contributing
74
117
 
75
118
  Bug reports and pull requests are welcome on GitHub at https://github.com/ccrockett/omniauth-keycloak. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -1,5 +1,5 @@
1
1
  module Omniauth
2
2
  module Keycloak
3
- VERSION = "1.2.0"
3
+ VERSION = "1.4.4"
4
4
  end
5
5
  end
@@ -1,54 +1,104 @@
1
1
  require 'omniauth'
2
2
  require 'omniauth-oauth2'
3
3
  require 'json/jwt'
4
+ require 'uri'
4
5
 
5
6
  module OmniAuth
6
7
  module Strategies
7
8
  class KeycloakOpenId < OmniAuth::Strategies::OAuth2
9
+
10
+ class Error < RuntimeError; end
11
+ class ConfigurationError < Error; end
12
+ class IntegrationError < Error; end
13
+
8
14
  attr_reader :authorize_url
9
15
  attr_reader :token_url
10
- attr_reader :cert
16
+ attr_reader :certs
11
17
 
12
18
  def setup_phase
19
+ super
20
+
13
21
  if @authorize_url.nil? || @token_url.nil?
22
+ prevent_site_option_mistake
23
+
14
24
  realm = options.client_options[:realm].nil? ? options.client_id : options.client_options[:realm]
15
25
  site = options.client_options[:site]
16
- response = Faraday.get "#{options.client_options[:site]}/auth/realms/#{realm}/.well-known/openid-configuration"
26
+
27
+ raise_on_failure = options.client_options.fetch(:raise_on_failure, false)
28
+
29
+ config_url = URI.join(site, "#{auth_url_base}/realms/#{realm}/.well-known/openid-configuration")
30
+
31
+ log :debug, "Going to get Keycloak configuration. URL: #{config_url}"
32
+ response = Faraday.get config_url
17
33
  if (response.status == 200)
18
- json = MultiJson.load(response.body)
34
+ json = JSON.parse(response.body)
35
+
19
36
  @certs_endpoint = json["jwks_uri"]
20
37
  @userinfo_endpoint = json["userinfo_endpoint"]
21
- @authorize_url = json["authorization_endpoint"].gsub(site, "")
22
- @token_url = json["token_endpoint"].gsub(site, "")
38
+ @authorize_url = URI(json["authorization_endpoint"]).path
39
+ @token_url = URI(json["token_endpoint"]).path
40
+
41
+ log_config(json)
42
+
23
43
  options.client_options.merge!({
24
44
  authorize_url: @authorize_url,
25
45
  token_url: @token_url
26
- })
46
+ })
47
+ log :debug, "Going to get certificates. URL: #{@certs_endpoint}"
27
48
  certs = Faraday.get @certs_endpoint
28
49
  if (certs.status == 200)
29
- json = MultiJson.load(certs.body)
30
- @cert = json["keys"][0]
50
+ json = JSON.parse(certs.body)
51
+ @certs = json["keys"]
52
+ log :debug, "Successfully got certificate. Certificate length: #{@certs.length}"
31
53
  else
32
- #TODO: Throw Error
33
- puts "Couldn't get Cert"
34
- end
54
+ message = "Coundn't get certificate. URL: #{@certs_endpoint}"
55
+ log :error, message
56
+ raise IntegrationError, message if raise_on_failure
57
+ end
35
58
  else
36
- #TODO: Throw Error
37
- puts response.status
59
+ message = "Keycloak configuration request failed with status: #{response.status}. " \
60
+ "URL: #{config_url}"
61
+ log :error, message
62
+ raise IntegrationError, message if raise_on_failure
38
63
  end
39
64
  end
40
65
  end
41
-
66
+
67
+ def auth_url_base
68
+ return '/auth' unless options.client_options[:base_url]
69
+ base_url = options.client_options[:base_url]
70
+ return base_url if (base_url == '' || base_url[0] == '/')
71
+
72
+ raise ConfigurationError, "Keycloak base_url option should start with '/'. Current value: #{base_url}"
73
+ end
74
+
75
+ def prevent_site_option_mistake
76
+ site = options.client_options[:site]
77
+ return unless site =~ /\/auth$/
78
+
79
+ raise ConfigurationError, "Keycloak site parameter should not include /auth part, only domain. Current value: #{site}"
80
+ end
81
+
82
+ def log_config(config_json)
83
+ log_keycloak_config = options.client_options.fetch(:log_keycloak_config, false)
84
+ log :debug, "Successfully got Keycloak config"
85
+ log :debug, "Keycloak config: #{config_json}" if log_keycloak_config
86
+ log :debug, "Certs endpoint: #{@certs_endpoint}"
87
+ log :debug, "Userinfo endpoint: #{@userinfo_endpoint}"
88
+ log :debug, "Authorize url: #{@authorize_url}"
89
+ log :debug, "Token url: #{@token_url}"
90
+ end
91
+
42
92
  def build_access_token
43
93
  verifier = request.params["code"]
44
- client.auth_code.get_token(verifier,
94
+ client.auth_code.get_token(verifier,
45
95
  {:redirect_uri => callback_url.gsub(/\?.+\Z/, "")}
46
- .merge(token_params.to_hash(:symbolize_keys => true)),
96
+ .merge(token_params.to_hash(:symbolize_keys => true)),
47
97
  deep_symbolize(options.auth_token_params))
48
98
  end
49
99
 
50
100
  uid{ raw_info['sub'] }
51
-
101
+
52
102
  info do
53
103
  {
54
104
  :name => raw_info['name'],
@@ -57,21 +107,22 @@ module OmniAuth
57
107
  :last_name => raw_info['family_name']
58
108
  }
59
109
  end
60
-
110
+
61
111
  extra do
62
112
  {
63
- 'raw_info' => raw_info
113
+ 'raw_info' => raw_info,
114
+ 'id_token' => access_token['id_token']
64
115
  }
65
116
  end
66
-
117
+
67
118
  def raw_info
68
119
  id_token_string = access_token.token
69
- jwk = JSON::JWK.new(@cert)
70
- id_token = JSON::JWT.decode id_token_string, jwk
120
+ jwks = JSON::JWK::Set.new(@certs)
121
+ id_token = JSON::JWT.decode id_token_string, jwks
71
122
  id_token
72
123
  end
73
124
 
74
125
  OmniAuth.config.add_camelization('keycloak_openid', 'KeycloakOpenId')
75
126
  end
76
127
  end
77
- end
128
+ end
@@ -4,13 +4,13 @@ Gem::Specification.new do |spec|
4
4
  spec.version = Omniauth::Keycloak::VERSION
5
5
  spec.authors = ["Cameron Crockett"]
6
6
  spec.email = ["cameron.crockett@ccrockett.com"]
7
-
7
+
8
8
  spec.description = %q{Omniauth strategy for Keycloak}
9
9
  spec.summary = spec.description
10
10
  spec.homepage = "https://github.com/ccrockett/omniauth-keycloak"
11
11
  spec.license = "MIT"
12
- spec.required_rubygems_version = '>= 1.3.5'
13
- spec.required_ruby_version = '>= 2.2'
12
+ spec.required_rubygems_version = '>= 3.1.2'
13
+ spec.required_ruby_version = '>= 2.6'
14
14
 
15
15
  # Specify which files should be added to the gem when it is released.
16
16
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -22,14 +22,15 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
-
26
- spec.add_dependency "omniauth", "~> 1.9.0"
27
- spec.add_dependency "omniauth-oauth2", "~> 1.6.0"
28
- spec.add_dependency "json-jwt", "~> 1.12"
29
25
 
30
- spec.add_development_dependency "bundler", "~> 1.16"
26
+ spec.add_dependency "omniauth", ">= 2.0"
27
+ spec.add_dependency "omniauth-oauth2", "~> 1.7.1"
28
+ spec.add_dependency "json-jwt", "~> 1.13.0"
29
+ spec.add_dependency "faraday"
30
+
31
+ spec.add_development_dependency "bundler", "~> 2.2"
31
32
  spec.add_development_dependency "rake", "~> 13.0"
32
- spec.add_development_dependency "rspec", "~> 3.0"
33
- spec.add_development_dependency 'simplecov', '~> 0.16.1'
34
- spec.add_development_dependency 'webmock', '~> 3.4.2'
33
+ spec.add_development_dependency "rspec", "~> 3.10"
34
+ spec.add_development_dependency 'simplecov', '~> 0.21'
35
+ spec.add_development_dependency 'webmock', '~> 3.14'
35
36
  end
@@ -1,41 +1,45 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe OmniAuth::Strategies::KeycloakOpenId do
4
- body = '{"issuer": "http://localhost:8080/auth/realms/example-realm",
5
- "authorization_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/auth",
6
- "token_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/token",
7
- "token_introspection_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/token/introspect",
8
- "userinfo_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/userinfo",
9
- "end_session_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/logout",
10
- "jwks_uri": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/certs",
11
- "check_session_iframe": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/login-status-iframe.html",
12
- "grant_types_supported": ["authorization_code", "implicit", "refresh_token", "password", "client_credentials"],
13
- "response_types_supported": ["code", "none", "id_token", "token", "id_token token", "code id_token", "code token", "code id_token token"],
14
- "subject_types_supported": ["public", "pairwise"],
15
- "id_token_signing_alg_values_supported": ["RS256"],
16
- "userinfo_signing_alg_values_supported": ["RS256"],
17
- "request_object_signing_alg_values_supported": ["none", "RS256"],
18
- "response_modes_supported": ["query", "fragment", "form_post"],
19
- "registration_endpoint": "http://localhost:8080/auth/realms/example-realm/clients-registrations/openid-connect",
20
- "token_endpoint_auth_methods_supported": ["private_key_jwt", "client_secret_basic", "client_secret_post"],
21
- "token_endpoint_auth_signing_alg_values_supported": ["RS256"],
22
- "claims_supported": ["sub", "iss", "auth_time", "name", "given_name", "family_name", "preferred_username", "email"],
23
- "claim_types_supported": ["normal"],
24
- "claims_parameter_supported": false,
25
- "scopes_supported": ["openid", "offline_access"],
26
- "request_parameter_supported": true,
27
- "request_uri_parameter_supported": true}'
4
+ let(:body) {
5
+ {
6
+ "issuer": "http://localhost:8080/auth/realms/example-realm",
7
+ "authorization_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/auth",
8
+ "token_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/token",
9
+ "token_introspection_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/token/introspect",
10
+ "userinfo_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/userinfo",
11
+ "end_session_endpoint": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/logout",
12
+ "jwks_uri": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/certs",
13
+ "check_session_iframe": "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/login-status-iframe.html",
14
+ "grant_types_supported": ["authorization_code", "implicit", "refresh_token", "password", "client_credentials"],
15
+ "response_types_supported": ["code", "none", "id_token", "token", "id_token token", "code id_token", "code token", "code id_token token"],
16
+ "subject_types_supported": ["public", "pairwise"],
17
+ "id_token_signing_alg_values_supported": ["RS256"],
18
+ "userinfo_signing_alg_values_supported": ["RS256"],
19
+ "request_object_signing_alg_values_supported": ["none", "RS256"],
20
+ "response_modes_supported": ["query", "fragment", "form_post"],
21
+ "registration_endpoint": "http://localhost:8080/auth/realms/example-realm/clients-registrations/openid-connect",
22
+ "token_endpoint_auth_methods_supported": ["private_key_jwt", "client_secret_basic", "client_secret_post"],
23
+ "token_endpoint_auth_signing_alg_values_supported": ["RS256"],
24
+ "claims_supported": ["sub", "iss", "auth_time", "name", "given_name", "family_name", "preferred_username", "email"],
25
+ "claim_types_supported": ["normal"],
26
+ "claims_parameter_supported": false,
27
+ "scopes_supported": ["openid", "offline_access"],
28
+ "request_parameter_supported": true,
29
+ "request_uri_parameter_supported": true
30
+ }
31
+ }
28
32
 
29
33
  context 'client options' do
30
34
  subject do
31
35
  stub_request(:get, "http://localhost:8080/auth/realms/example-realm/.well-known/openid-configuration")
32
- .to_return(status: 200, body: body, headers: {})
36
+ .to_return(status: 200, body: JSON.generate(body), headers: {})
33
37
  stub_request(:get, "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/certs")
34
38
  .to_return(status: 404, body: "", headers: {})
35
39
  OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', 'Example-Client', 'b53c572b-9f3b-4e79-bf8b-f03c799ba6ec',
36
- client_options: {site: 'http://localhost:8080', realm: 'example-realm'})
40
+ client_options: {site: 'http://localhost:8080/', realm: 'example-realm'})
37
41
  end
38
-
42
+
39
43
  it 'should have the correct keycloak token url' do
40
44
  subject.setup_phase
41
45
  expect(subject.token_url).to eq('/auth/realms/example-realm/protocol/openid-connect/token')
@@ -46,4 +50,137 @@ RSpec.describe OmniAuth::Strategies::KeycloakOpenId do
46
50
  expect(subject.authorize_url).to eq('/auth/realms/example-realm/protocol/openid-connect/auth')
47
51
  end
48
52
  end
53
+
54
+ describe 'client base_url option set' do
55
+ context 'to blank string' do
56
+ let(:new_body_endpoints) {
57
+ {
58
+ "authorization_endpoint": "http://localhost:8080/realms/example-realm/protocol/openid-connect/auth",
59
+ "token_endpoint": "http://localhost:8080/realms/example-realm/protocol/openid-connect/token",
60
+ "jwks_uri": "http://localhost:8080/realms/example-realm/protocol/openid-connect/certs"
61
+ }
62
+ }
63
+
64
+ subject do
65
+ stub_request(:get, "http://localhost:8080/realms/example-realm/.well-known/openid-configuration")
66
+ .to_return(status: 200, body: JSON.generate(body.merge(new_body_endpoints)), headers: {})
67
+ stub_request(:get, "http://localhost:8080/realms/example-realm/protocol/openid-connect/certs")
68
+ .to_return(status: 404, body: "", headers: {})
69
+ OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', 'Example-Client', 'b53c572b-9f3b-4e79-bf8b-f03c799ba6ec',
70
+ client_options: {site: 'http://localhost:8080/', realm: 'example-realm', base_url: ''})
71
+ end
72
+
73
+ it 'should have the correct keycloak token url' do
74
+ subject.setup_phase
75
+ expect(subject.token_url).to eq('/realms/example-realm/protocol/openid-connect/token')
76
+ end
77
+
78
+ it 'should have the correct keycloak authorization url' do
79
+ subject.setup_phase
80
+ expect(subject.authorize_url).to eq('/realms/example-realm/protocol/openid-connect/auth')
81
+ end
82
+ end
83
+
84
+ context 'to invalid string' do
85
+ subject do
86
+ stub_request(:get, "http://localhost:8080/realms/example-realm/.well-known/openid-configuration")
87
+ .to_return(status: 200, body: JSON.generate(body), headers: {})
88
+ stub_request(:get, "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/certs")
89
+ .to_return(status: 404, body: "", headers: {})
90
+ OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', 'Example-Client', 'b53c572b-9f3b-4e79-bf8b-f03c799ba6ec',
91
+ client_options: {site: 'http://localhost:8080/', realm: 'example-realm', base_url: 'test'})
92
+ end
93
+
94
+ it 'raises Configuration Error' do
95
+ expect{ subject.setup_phase }
96
+ .to raise_error(OmniAuth::Strategies::KeycloakOpenId::ConfigurationError)
97
+ end
98
+ end
99
+
100
+ context 'to /authorize' do
101
+
102
+ let(:new_body_endpoints) {
103
+ {
104
+ "authorization_endpoint": "http://localhost:8080/authorize/realms/example-realm/protocol/openid-connect/auth",
105
+ "token_endpoint": "http://localhost:8080/authorize/realms/example-realm/protocol/openid-connect/token",
106
+ "jwks_uri": "http://localhost:8080/authorize/realms/example-realm/protocol/openid-connect/certs"
107
+ }
108
+ }
109
+
110
+ subject do
111
+ stub_request(:get, "http://localhost:8080/authorize/realms/example-realm/.well-known/openid-configuration")
112
+ .to_return(status: 200, body: JSON.generate(body.merge(new_body_endpoints)), headers: {})
113
+ stub_request(:get, "http://localhost:8080/authorize/realms/example-realm/protocol/openid-connect/certs")
114
+ .to_return(status: 404, body: "", headers: {})
115
+ OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', 'Example-Client', 'b53c572b-9f3b-4e79-bf8b-f03c799ba6ec',
116
+ client_options: {site: 'http://localhost:8080/', realm: 'example-realm', base_url: '/authorize'})
117
+ end
118
+
119
+ it 'should have the correct keycloak token url' do
120
+ subject.setup_phase
121
+ expect(subject.token_url).to eq('/authorize/realms/example-realm/protocol/openid-connect/token')
122
+ end
123
+
124
+ it 'should have the correct keycloak authorization url' do
125
+ subject.setup_phase
126
+ expect(subject.authorize_url).to eq('/authorize/realms/example-realm/protocol/openid-connect/auth')
127
+ end
128
+ end
129
+ end
130
+
131
+ context 'client setup with a proc' do
132
+ subject do
133
+ OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', setup: proc { throw :setup_proc_was_called })
134
+ end
135
+
136
+ it 'should call the proc' do
137
+ expect { subject.setup_phase }.to throw_symbol :setup_proc_was_called
138
+ end
139
+ end
140
+
141
+ describe 'errors processing' do
142
+ context 'when site contains /auth part' do
143
+ subject do
144
+ OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', 'Example-Client', 'b53c572b-9f3b-4e79-bf8b-f03c799ba6ec',
145
+ client_options: {site: 'http://localhost:8080/auth', realm: 'example-realm', raise_on_failure: true})
146
+ end
147
+
148
+ it 'raises Configuration Error' do
149
+ expect{ subject.setup_phase }
150
+ .to raise_error(OmniAuth::Strategies::KeycloakOpenId::ConfigurationError)
151
+ end
152
+ end
153
+
154
+ context 'when raise_on_failure option is true' do
155
+ context 'when openid configuration endpoint returns error response' do
156
+ subject do
157
+ stub_request(:get, "http://localhost:8080/auth/realms/example-realm/.well-known/openid-configuration")
158
+ .to_return(status: 404, body: "", headers: {})
159
+ OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', 'Example-Client', 'b53c572b-9f3b-4e79-bf8b-f03c799ba6ec',
160
+ client_options: {site: 'http://localhost:8080', realm: 'example-realm', raise_on_failure: true})
161
+ end
162
+
163
+ it 'raises Integration Error' do
164
+ expect{ subject.setup_phase }
165
+ .to raise_error(OmniAuth::Strategies::KeycloakOpenId::IntegrationError)
166
+ end
167
+ end
168
+
169
+ context 'when certificates endpoint returns error response' do
170
+ subject do
171
+ stub_request(:get, "http://localhost:8080/auth/realms/example-realm/.well-known/openid-configuration")
172
+ .to_return(status: 200, body: JSON.generate(body), headers: {})
173
+ stub_request(:get, "http://localhost:8080/auth/realms/example-realm/protocol/openid-connect/certs")
174
+ .to_return(status: 404, body: "", headers: {})
175
+ OmniAuth::Strategies::KeycloakOpenId.new('keycloak-openid', 'Example-Client', 'b53c572b-9f3b-4e79-bf8b-f03c799ba6ec',
176
+ client_options: {site: 'http://localhost:8080', realm: 'example-realm', raise_on_failure: true})
177
+ end
178
+
179
+ it 'raises Integration Error' do
180
+ expect{ subject.setup_phase }
181
+ .to raise_error(OmniAuth::Strategies::KeycloakOpenId::IntegrationError)
182
+ end
183
+ end
184
+ end
185
+ end
49
186
  end
metadata CHANGED
@@ -1,71 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-keycloak
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Crockett
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-28 00:00:00.000000000 Z
11
+ date: 2022-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: omniauth
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.9.0
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.9.0
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: omniauth-oauth2
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.6.0
33
+ version: 1.7.1
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.6.0
40
+ version: 1.7.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: json-jwt
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.12'
47
+ version: 1.13.0
48
48
  type: :runtime
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: '1.12'
54
+ version: 1.13.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '1.16'
75
+ version: '2.2'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '1.16'
82
+ version: '2.2'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rake
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -86,42 +100,42 @@ dependencies:
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '3.0'
103
+ version: '3.10'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '3.0'
110
+ version: '3.10'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: simplecov
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: 0.16.1
117
+ version: '0.21'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: 0.16.1
124
+ version: '0.21'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: webmock
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: 3.4.2
131
+ version: '3.14'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
- version: 3.4.2
138
+ version: '3.14'
125
139
  description: Omniauth strategy for Keycloak
126
140
  email:
127
141
  - cameron.crockett@ccrockett.com
@@ -133,6 +147,7 @@ files:
133
147
  - ".rspec"
134
148
  - ".travis.yml"
135
149
  - ".vscode/settings.json"
150
+ - CHANGELOG.md
136
151
  - CODE_OF_CONDUCT.md
137
152
  - Gemfile
138
153
  - Gemfile.lock
@@ -159,14 +174,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
159
174
  requirements:
160
175
  - - ">="
161
176
  - !ruby/object:Gem::Version
162
- version: '2.2'
177
+ version: '2.6'
163
178
  required_rubygems_version: !ruby/object:Gem::Requirement
164
179
  requirements:
165
180
  - - ">="
166
181
  - !ruby/object:Gem::Version
167
- version: 1.3.5
182
+ version: 3.1.2
168
183
  requirements: []
169
- rubygems_version: 3.0.3
184
+ rubygems_version: 3.1.6
170
185
  signing_key:
171
186
  specification_version: 4
172
187
  summary: Omniauth strategy for Keycloak