-
Notifications
You must be signed in to change notification settings - Fork 981
/
oidc_jwt_validate.rb
50 lines (46 loc) · 1.55 KB
/
oidc_jwt_validate.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class OidcJwtValidate
attr_reader :decoded_token
delegate :logger, to: :Rails
def initialize(jwt_token)
@jwt_token = jwt_token
end
def decoded_payload
# OpenSSL#set_key method does not support ruby version < 2.4.0, apparently the JWT gem uses
# OpenSSL#set_key method for all ruby version. We must remove this condition once new version
# of the JWT(2.2.2) is released.
unless OpenSSL::PKey::RSA.new.respond_to?(:set_key)
Foreman::Logging.logger('app').error "SSO feature is not available for Ruby < 2.4.0"
return nil
end
JWT.decode(@jwt_token, nil, true,
{ aud: Setting['oidc_audience'],
verify_aud: true,
iss: Setting['oidc_issuer'],
verify_iss: true,
algorithms: [Setting['oidc_algorithm']],
jwks: jwks_loader }
).first
rescue JWT::DecodeError => e
Foreman::Logging.exception('Failed to decode JWT', e)
nil
end
private
def jwks_loader(options = {})
response = RestClient::Request.execute(
:url => Setting['oidc_jwks_url'],
:method => :get,
:verify_ssl => true
)
json_response = JSON.parse(response)
if json_response.is_a?(Hash)
jwks_keys = json_response['keys']
@cached_keys = nil if options[:invalidate] # need to reload the keys
@cached_keys ||= { keys: jwks_keys.map(&:symbolize_keys) }
else
raise JSON::ParserError.new('Invalid JWKS response')
end
rescue RestClient::Exception, SocketError, JSON::ParserError => e
Foreman::Logging.exception('Failed to load the JWKS', e)
{}
end
end