openid_connect 0.6.1 → 0.7.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/.travis.yml +1 -1
- data/README.rdoc +3 -1
- data/VERSION +1 -1
- data/lib/openid_connect/access_token.rb +1 -2
- data/lib/openid_connect/client.rb +2 -6
- data/lib/openid_connect/client/registrar.rb +59 -123
- data/lib/openid_connect/discovery.rb +0 -2
- data/lib/openid_connect/discovery/provider.rb +3 -1
- data/lib/openid_connect/discovery/provider/config/response.rb +57 -78
- data/lib/openid_connect/request_object.rb +1 -8
- data/lib/openid_connect/request_object/{user_info.rb → userinfo.rb} +0 -0
- data/lib/openid_connect/response_object/id_token.rb +1 -1
- data/lib/openid_connect/response_object/userinfo.rb +3 -0
- data/lib/openid_connect/response_object/{user_info → userinfo}/open_id.rb +7 -6
- data/lib/openid_connect/response_object/{user_info → userinfo}/open_id/address.rb +0 -0
- data/openid_connect.gemspec +2 -2
- data/spec/helpers/webmock_helper.rb +2 -1
- data/spec/mock_response/discovery/config.json +3 -2
- data/spec/mock_response/public_keys/{jwk.json → jwks.json} +1 -1
- data/spec/mock_response/{user_info → userinfo}/openid.json +0 -0
- data/spec/openid_connect/access_token_spec.rb +7 -6
- data/spec/openid_connect/client/registrar_spec.rb +82 -207
- data/spec/openid_connect/client_spec.rb +2 -2
- data/spec/openid_connect/discovery/provider/config/response_spec.rb +53 -286
- data/spec/openid_connect/discovery/provider/config_spec.rb +11 -12
- data/spec/openid_connect/discovery/provider_spec.rb +1 -1
- data/spec/openid_connect/request_object_spec.rb +4 -4
- data/spec/openid_connect/response_object/id_token_spec.rb +4 -4
- data/spec/openid_connect/response_object/user_info/open_id_spec.rb +1 -0
- metadata +17 -20
- data/Gemfile.lock +0 -102
- data/lib/openid_connect/response_object/user_info.rb +0 -3
- data/spec/mock_response/public_keys/x509.pem +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e2f19e123a06f31e0d6081e5ec4f8b05eaa56b7
|
4
|
+
data.tar.gz: 4a90cb5da6acf0bc5382562a047badd6dec4efd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 061da991172819aca5f12d331a8dc05116821b3bf4b56843f5c9a0cf987e3369756bad429fe135ee49322f126154d65d8f28c3b9adabac8c5acbf0380cf6264f
|
7
|
+
data.tar.gz: 814e741ecf52b5669278a88412f16b4ff2141029709bdf151f1a601b371650a7090df6de3f5eff1883b93e8d909237cc98fc4d8d7562ffadb8b50610184017e3
|
data/.travis.yml
CHANGED
data/README.rdoc
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
OpenID Connect Server & Client Library
|
4
4
|
|
5
|
+
{<img src="https://secure.travis-ci.org/nov/openid_connect.png" />}[http://travis-ci.org/nov/openid_connect]
|
6
|
+
|
5
7
|
== Installation
|
6
8
|
|
7
9
|
gem install openid_connect
|
@@ -25,7 +27,7 @@ OpenID Connect Server & Client Library
|
|
25
27
|
* Source on GitHub (https://github.com/nov/openid_connect_sample_rp)
|
26
28
|
|
27
29
|
== Note on Patches/Pull Requests
|
28
|
-
|
30
|
+
|
29
31
|
* Fork the project.
|
30
32
|
* Make your feature addition or bug fix.
|
31
33
|
* Add tests for it. This is important so I don't break it in a
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0
|
@@ -14,7 +14,6 @@ module OpenIDConnect
|
|
14
14
|
end
|
15
15
|
ResponseObject::UserInfo::OpenID.new hash
|
16
16
|
end
|
17
|
-
alias_method :user_info!, :userinfo!
|
18
17
|
|
19
18
|
private
|
20
19
|
|
@@ -22,7 +21,7 @@ module OpenIDConnect
|
|
22
21
|
res = yield
|
23
22
|
case res.status
|
24
23
|
when 200
|
25
|
-
JSON.parse
|
24
|
+
JSON.parse(res.body).with_indifferent_access
|
26
25
|
when 400
|
27
26
|
raise BadRequest.new('API Access Faild', res)
|
28
27
|
when 401
|
@@ -1,13 +1,10 @@
|
|
1
1
|
module OpenIDConnect
|
2
2
|
class Client < Rack::OAuth2::Client
|
3
3
|
attr_optional :userinfo_endpoint, :expires_in
|
4
|
-
alias_method :user_info_endpoint, :userinfo_endpoint
|
5
|
-
alias_method :user_info_endpoint=, :userinfo_endpoint=
|
6
4
|
|
7
5
|
def initialize(attributes = {})
|
8
|
-
attributes[:userinfo_endpoint] ||= attributes[:user_info_endpoint]
|
9
6
|
super attributes
|
10
|
-
self.userinfo_endpoint ||= '/
|
7
|
+
self.userinfo_endpoint ||= '/userinfo'
|
11
8
|
end
|
12
9
|
|
13
10
|
def authorization_uri(params = {})
|
@@ -19,7 +16,6 @@ module OpenIDConnect
|
|
19
16
|
def userinfo_uri
|
20
17
|
absolute_uri_for userinfo_endpoint
|
21
18
|
end
|
22
|
-
alias_method :user_info_uri, :userinfo_uri
|
23
19
|
|
24
20
|
private
|
25
21
|
|
@@ -30,7 +26,7 @@ module OpenIDConnect
|
|
30
26
|
end
|
31
27
|
|
32
28
|
def handle_success_response(response)
|
33
|
-
token_hash = JSON.parse
|
29
|
+
token_hash = JSON.parse(response.body).with_indifferent_access
|
34
30
|
case token_type = token_hash[:token_type].try(:downcase)
|
35
31
|
when 'bearer'
|
36
32
|
AccessToken.new token_hash.merge(client: self)
|
@@ -5,22 +5,20 @@ module OpenIDConnect
|
|
5
5
|
|
6
6
|
class RegistrationFailed < HttpError; end
|
7
7
|
|
8
|
+
cattr_accessor :plurar_uri_attributes, :metadata_attributes
|
9
|
+
singular_uri_attributes = [
|
10
|
+
:logo_uri,
|
11
|
+
:client_uri,
|
12
|
+
:policy_uri,
|
13
|
+
:tos_uri,
|
14
|
+
:jwks_uri,
|
15
|
+
:sector_identifier_uri,
|
16
|
+
:initiate_login_uri
|
17
|
+
]
|
8
18
|
singular_attributes = [
|
9
|
-
:operation,
|
10
|
-
:client_id,
|
11
|
-
:client_secret,
|
12
|
-
:access_token,
|
13
19
|
:application_type,
|
14
20
|
:client_name,
|
15
|
-
:logo_url,
|
16
21
|
:token_endpoint_auth_method,
|
17
|
-
:policy_url,
|
18
|
-
:tos_url,
|
19
|
-
:jwk_url,
|
20
|
-
:jwk_encryption_url,
|
21
|
-
:x509_url,
|
22
|
-
:x509_encryption_url,
|
23
|
-
:sector_identifier_url,
|
24
22
|
:subject_type,
|
25
23
|
:request_object_signing_alg,
|
26
24
|
:userinfo_signed_response_alg,
|
@@ -30,81 +28,47 @@ module OpenIDConnect
|
|
30
28
|
:id_token_encrypted_response_alg,
|
31
29
|
:id_token_encrypted_response_enc,
|
32
30
|
:default_max_age,
|
33
|
-
:require_auth_time
|
34
|
-
|
35
|
-
|
36
|
-
:
|
31
|
+
:require_auth_time
|
32
|
+
] + singular_uri_attributes
|
33
|
+
self.plurar_uri_attributes = [
|
34
|
+
:redirect_uris,
|
35
|
+
:post_logout_redirect_uris,
|
36
|
+
:request_uris
|
37
37
|
]
|
38
38
|
plurar_attributes = [
|
39
|
+
:response_types,
|
40
|
+
:grant_types,
|
39
41
|
:contacts,
|
42
|
+
:default_acr_values,
|
43
|
+
] + plurar_uri_attributes
|
44
|
+
self.metadata_attributes = singular_attributes + plurar_attributes
|
45
|
+
required_metadata_attributes = [
|
40
46
|
:redirect_uris
|
41
47
|
]
|
42
48
|
attr_required :endpoint
|
43
|
-
attr_optional
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
else
|
52
|
-
value
|
53
|
-
end
|
54
|
-
end
|
55
|
-
alias_method_chain _attr_, :split
|
56
|
-
end
|
57
|
-
|
58
|
-
validates :operation, presence: true
|
59
|
-
validates :client_id, presence: {if: ->(c) { ['client_update', 'rotate_secret'].include?(c.operation.to_s) }}
|
60
|
-
validates :sector_identifier_url, presence: {if: :sector_identifier_required?}
|
61
|
-
|
62
|
-
validates :operation, inclusion: {in: ['client_register', 'rotate_secret', 'client_update']}
|
63
|
-
validates :application_type, inclusion: {in: ['native', 'web']}, allow_nil: true
|
64
|
-
validates :subject_type, inclusion: {in: ['pairwise', 'public']}, allow_nil: true
|
65
|
-
validates :token_endpoint_auth_method, inclusion: {
|
66
|
-
in: ['client_secret_post', 'client_secret_basic', 'client_secret_jwt', 'private_key_jwt']
|
67
|
-
}, allow_nil: true
|
68
|
-
|
69
|
-
validates(
|
70
|
-
:logo_url,
|
71
|
-
:policy_url,
|
72
|
-
:tos_url,
|
73
|
-
:jwk_url,
|
74
|
-
:jwk_encryption_url,
|
75
|
-
:x509_url,
|
76
|
-
:x509_encryption_url,
|
77
|
-
:sector_identifier_url,
|
78
|
-
:initiate_login_uri,
|
79
|
-
:post_logout_redirect_url,
|
80
|
-
url: true,
|
81
|
-
allow_nil: true
|
82
|
-
)
|
83
|
-
|
49
|
+
attr_optional :initial_access_token
|
50
|
+
attr_required *required_metadata_attributes
|
51
|
+
attr_optional *(metadata_attributes - required_metadata_attributes)
|
52
|
+
|
53
|
+
validates *required_attributes, presence: true
|
54
|
+
validates :sector_identifier_uri, presence: {if: :sector_identifier_required?}
|
55
|
+
validates *singular_uri_attributes, url: true, allow_nil: true
|
56
|
+
validate :validate_plurar_uri_attributes
|
84
57
|
validate :validate_contacts
|
85
|
-
validate :validate_redirect_uris
|
86
|
-
validate :validate_key_urls
|
87
|
-
validate :validate_signature_algorithms
|
88
|
-
validate :validate_encription_algorithms
|
89
58
|
|
90
59
|
def initialize(endpoint, attributes = {})
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
else
|
96
|
-
attributes[_attr_].try(:to_s)
|
97
|
-
end
|
98
|
-
self.send "#{_attr_}=", value
|
60
|
+
self.endpoint = endpoint
|
61
|
+
self.initial_access_token = attributes[:initial_access_token]
|
62
|
+
self.class.metadata_attributes.each do |_attr_|
|
63
|
+
self.send "#{_attr_}=", attributes[_attr_]
|
99
64
|
end
|
100
|
-
attr_missing!
|
101
65
|
end
|
102
66
|
|
103
67
|
def sector_identifier
|
104
|
-
if valid_uri?(
|
105
|
-
URI.parse(
|
68
|
+
if valid_uri?(sector_identifier_uri)
|
69
|
+
URI.parse(sector_identifier_uri).host
|
106
70
|
else
|
107
|
-
hosts =
|
71
|
+
hosts = redirect_uris.collect do |redirect_uri|
|
108
72
|
if valid_uri?(redirect_uri, nil)
|
109
73
|
URI.parse(redirect_uri).host
|
110
74
|
else
|
@@ -121,32 +85,21 @@ module OpenIDConnect
|
|
121
85
|
|
122
86
|
def as_json(options = {})
|
123
87
|
validate!
|
124
|
-
|
125
|
-
value = self.send
|
126
|
-
hash.merge! _attr_ =>
|
127
|
-
|
128
|
-
value.collect(&:to_s).join(' ')
|
129
|
-
else
|
130
|
-
value
|
131
|
-
end
|
132
|
-
end.delete_if do |key, value|
|
133
|
-
value.nil?
|
88
|
+
self.class.metadata_attributes.inject({}) do |hash, _attr_|
|
89
|
+
value = self.send _attr_
|
90
|
+
hash.merge! _attr_ => value unless value.nil?
|
91
|
+
hash
|
134
92
|
end
|
135
93
|
end
|
136
94
|
|
137
95
|
def register!
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
def rotate_secret!
|
143
|
-
self.operation = 'rotate_secret'
|
144
|
-
post!
|
96
|
+
handle_response do
|
97
|
+
http_client.post endpoint, to_json, 'Content-Type' => 'application/json'
|
98
|
+
end
|
145
99
|
end
|
146
100
|
|
147
|
-
def
|
148
|
-
|
149
|
-
post!
|
101
|
+
def read
|
102
|
+
# TODO: Do we want this feature even if we don't have rotate secret nor update metadata support?
|
150
103
|
end
|
151
104
|
|
152
105
|
def validate!
|
@@ -156,14 +109,13 @@ module OpenIDConnect
|
|
156
109
|
private
|
157
110
|
|
158
111
|
def sector_identifier_required?
|
159
|
-
subject_type == 'pairwise' &&
|
112
|
+
subject_type.to_s == 'pairwise' &&
|
160
113
|
sector_identifier.blank?
|
161
114
|
end
|
162
115
|
|
163
116
|
def valid_uri?(uri, schemes = ['http', 'https'])
|
164
117
|
# NOTE: specify nil for schemes to allow any schemes
|
165
|
-
URI::regexp(schemes).match(uri).present?
|
166
|
-
URI.parse(uri).fragment.blank?
|
118
|
+
URI::regexp(schemes).match(uri).present?
|
167
119
|
end
|
168
120
|
|
169
121
|
def validate_contacts
|
@@ -180,42 +132,26 @@ module OpenIDConnect
|
|
180
132
|
end
|
181
133
|
end
|
182
134
|
|
183
|
-
def
|
184
|
-
|
185
|
-
|
186
|
-
|
135
|
+
def validate_plurar_uri_attributes
|
136
|
+
self.class.plurar_uri_attributes.each do |_attr_|
|
137
|
+
if (uris = self.send(_attr_))
|
138
|
+
include_invalid = uris.any? do |uri|
|
139
|
+
!valid_uri?(uri, nil)
|
140
|
+
end
|
141
|
+
errors.add _attr_, 'includes invalid URL' if include_invalid
|
187
142
|
end
|
188
|
-
errors.add :redirect_uris, 'includes invalid URL' if include_invalid
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
def validate_key_urls
|
193
|
-
# TODO
|
194
|
-
end
|
195
|
-
|
196
|
-
def validate_signature_algorithms
|
197
|
-
# TODO
|
198
|
-
end
|
199
|
-
|
200
|
-
def validate_encription_algorithms
|
201
|
-
# TODO
|
202
|
-
end
|
203
|
-
|
204
|
-
def post!
|
205
|
-
handle_response do
|
206
|
-
http_client.post endpoint, as_json
|
207
143
|
end
|
208
144
|
end
|
209
145
|
|
210
146
|
def http_client
|
211
|
-
case
|
147
|
+
case initial_access_token
|
212
148
|
when nil
|
213
149
|
OpenIDConnect.http_client
|
214
150
|
when Rack::OAuth2::AccessToken::Bearer
|
215
|
-
|
151
|
+
initial_access_token
|
216
152
|
else
|
217
153
|
Rack::OAuth2::AccessToken::Bearer.new(
|
218
|
-
access_token:
|
154
|
+
access_token: initial_access_token
|
219
155
|
)
|
220
156
|
end
|
221
157
|
end
|
@@ -231,7 +167,7 @@ module OpenIDConnect
|
|
231
167
|
end
|
232
168
|
|
233
169
|
def handle_success_response(response)
|
234
|
-
credentials = JSON.parse
|
170
|
+
credentials = JSON.parse(response.body).with_indifferent_access
|
235
171
|
Client.new(
|
236
172
|
identifier: credentials[:client_id],
|
237
173
|
secret: credentials[:client_secret],
|
@@ -2,6 +2,8 @@ module OpenIDConnect
|
|
2
2
|
module Discovery
|
3
3
|
module Provider
|
4
4
|
module Issuer
|
5
|
+
REL_VALUE = 'http://openid.net/specs/connect/1.0/issuer'
|
6
|
+
|
5
7
|
def issuer
|
6
8
|
self.link_for(REL_VALUE)[:href]
|
7
9
|
end
|
@@ -16,7 +18,7 @@ module OpenIDConnect
|
|
16
18
|
end
|
17
19
|
response = WebFinger.discover!(
|
18
20
|
resource,
|
19
|
-
rel: REL_VALUE
|
21
|
+
rel: Issuer::REL_VALUE
|
20
22
|
)
|
21
23
|
response.extend Issuer
|
22
24
|
response
|
@@ -2,112 +2,91 @@ module OpenIDConnect
|
|
2
2
|
module Discovery
|
3
3
|
module Provider
|
4
4
|
class Config
|
5
|
-
class Response
|
6
|
-
include AttrOptional
|
5
|
+
class Response
|
6
|
+
include ActiveModel::Validations, AttrRequired, AttrOptional
|
7
7
|
|
8
|
+
cattr_accessor :metadata_attributes
|
8
9
|
attr_reader :raw
|
9
|
-
|
10
|
-
:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
10
|
+
uri_attributes = {
|
11
|
+
required: [
|
12
|
+
:issuer,
|
13
|
+
:jwks_uri
|
14
|
+
],
|
15
|
+
optional: [
|
16
|
+
:authorization_endpoint,
|
17
|
+
:token_endpoint,
|
18
|
+
:userinfo_endpoint,
|
19
|
+
:check_session_endpoint,
|
20
|
+
:end_session_endpoint,
|
21
|
+
:registration_endpoint,
|
22
|
+
:service_documentation,
|
23
|
+
:op_policy_uri,
|
24
|
+
:op_tos_uri
|
25
|
+
]
|
26
|
+
}
|
27
|
+
attr_required *(uri_attributes[:required] + [
|
24
28
|
:response_types_supported,
|
25
|
-
:acr_values_supported,
|
26
29
|
:subject_types_supported,
|
27
|
-
:
|
30
|
+
:id_token_signing_alg_values_supported
|
31
|
+
])
|
32
|
+
attr_optional *(uri_attributes[:optional] + [
|
33
|
+
:scopes_supported,
|
34
|
+
:grant_types_supported,
|
35
|
+
:acr_values_supported,
|
28
36
|
:userinfo_signing_alg_values_supported,
|
29
37
|
:userinfo_encryption_alg_values_supported,
|
30
38
|
:userinfo_encryption_enc_values_supported,
|
31
|
-
:id_token_signing_alg_values_supported,
|
32
39
|
:id_token_encryption_alg_values_supported,
|
33
40
|
:id_token_encryption_enc_values_supported,
|
34
41
|
:request_object_signing_alg_values_supported,
|
35
42
|
:request_object_encryption_alg_values_supported,
|
36
43
|
:request_object_encryption_enc_values_supported,
|
37
44
|
:token_endpoint_auth_methods_supported,
|
38
|
-
:token_endpoint_auth_signing_alg_values_supported
|
39
|
-
|
40
|
-
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
:token_endpoint_auth_signing_alg_values_supported,
|
46
|
+
:display_values_supported,
|
47
|
+
:claim_types_supported,
|
48
|
+
:claims_supported,
|
49
|
+
:claims_locales_supported,
|
50
|
+
:ui_locales_supported,
|
51
|
+
:claims_parameter_supported,
|
52
|
+
:request_parameter_supported,
|
53
|
+
:request_uri_parameter_supported,
|
54
|
+
:require_request_uri_registration
|
55
|
+
])
|
56
|
+
|
57
|
+
validates *required_attributes, presence: true
|
58
|
+
validates *uri_attributes.values.flatten, url: true, allow_nil: true
|
50
59
|
|
51
60
|
def initialize(hash)
|
52
|
-
optional_attributes.each do |key|
|
61
|
+
(required_attributes + optional_attributes).each do |key|
|
53
62
|
self.send "#{key}=", hash[key]
|
54
63
|
end
|
55
|
-
self.userinfo_endpoint ||= hash[:user_info_endpoint]
|
56
|
-
self.userinfo_signing_alg_values_supported ||= hash[:user_info_signing_alg_values_supported]
|
57
|
-
self.userinfo_encryption_alg_values_supported ||= hash[:user_info_encryption_alg_values_supported]
|
58
|
-
self.userinfo_encryption_enc_values_supported ||= hash[:user_info_encryption_enc_values_supported]
|
59
|
-
self.version ||= '3.0'
|
60
64
|
@raw = hash
|
61
65
|
end
|
62
66
|
|
63
67
|
def as_json(options = {})
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
hash.delete_if do |key, value|
|
70
|
-
value.nil?
|
68
|
+
validate!
|
69
|
+
(required_attributes + optional_attributes).inject({}) do |hash, _attr_|
|
70
|
+
value = self.send _attr_
|
71
|
+
hash.merge! _attr_ => value unless value.nil?
|
72
|
+
hash
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
74
|
-
def
|
75
|
-
|
76
|
+
def validate!
|
77
|
+
valid? or raise ValidationFailed.new(self)
|
76
78
|
end
|
77
79
|
|
78
|
-
def
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
else
|
84
|
-
signing_key
|
85
|
-
end
|
80
|
+
def jwks
|
81
|
+
@jwks ||= JSON.parse(
|
82
|
+
OpenIDConnect.http_client.get_content(jwks_uri)
|
83
|
+
).with_indifferent_access
|
84
|
+
JSON::JWK::Set.new @jwks[:keys]
|
86
85
|
end
|
87
86
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
endpoint = if for_encryption
|
92
|
-
x509_encryption_url || x509_url
|
93
|
-
else
|
94
|
-
x509_url
|
95
|
-
end
|
96
|
-
if endpoint
|
97
|
-
cert = OpenSSL::X509::Certificate.new OpenIDConnect.http_client.get_content(endpoint)
|
98
|
-
cert.public_key
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def jwk_public_key(for_encryption = false)
|
103
|
-
endpoint = if for_encryption
|
104
|
-
jwk_encryption_url || jwk_url
|
105
|
-
else
|
106
|
-
jwk_url
|
107
|
-
end
|
108
|
-
if endpoint
|
109
|
-
jwk_set = JSON.parse OpenIDConnect.http_client.get_content(endpoint), symbolize_names: true
|
110
|
-
JSON::JWK.decode jwk_set[:keys].first
|
87
|
+
def public_keys
|
88
|
+
@public_keys ||= jwks.collect do |jwk|
|
89
|
+
JSON::JWK.decode jwk
|
111
90
|
end
|
112
91
|
end
|
113
92
|
end
|