authentic-rb 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/authentic/key_manager.rb +0 -4
- data/lib/authentic/key_store.rb +6 -14
- data/lib/authentic/validator.rb +11 -50
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e863c99c2e2d4b8312101c42e2a7079e90d610756156e0a2c57906c1afdf131
|
4
|
+
data.tar.gz: 72dff9af3c38d789c32398000f56fc378f355a5f52369a553f389e49692ac7f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90e92d91ef2076db91ca8251ca61ce756636ff0c1e1432ecf1926bbbf8cba1c47e250585e7f841f99b9495673379df2957744cc8371be5fa7818f0d2efb6cd71
|
7
|
+
data.tar.gz: 725f1a1e56b8f22d98e18941cde23a66719b3725457938aa1fa43e175aa136e61ac1f95575af4acd17fa62f00bbbebc35febf58a8d9f7544ea5835d9711b1b65
|
data/lib/authentic/key_store.rb
CHANGED
@@ -11,16 +11,7 @@ module Authentic
|
|
11
11
|
|
12
12
|
def initialize(max_age, data = {})
|
13
13
|
@data = data
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def configure_max_age(max_age)
|
18
|
-
@max_age = max_age
|
19
|
-
@max_age_seconds = human_time_to_seconds
|
20
|
-
end
|
21
|
-
|
22
|
-
def reset_all
|
23
|
-
@data = {}
|
14
|
+
@max_age_seconds = human_time_to_seconds(max_age)
|
24
15
|
end
|
25
16
|
|
26
17
|
# Public: Sets data, and wraps it in OIDCKey class if not presented as that type.
|
@@ -70,13 +61,14 @@ module Authentic
|
|
70
61
|
|
71
62
|
# frozen_string_literal: true
|
72
63
|
|
73
|
-
# Internal: converts human time to seconds for consumption of the cache service. Format
|
64
|
+
# Internal: converts human time to seconds for consumption of the cache service. Format example: `10h5m30s`.
|
65
|
+
# All units are optional.
|
74
66
|
#
|
75
|
-
#
|
67
|
+
# time - time to convert, it is a string that represents time in hours, minutes, and seconds.
|
76
68
|
#
|
77
69
|
# Returns seconds.
|
78
|
-
def human_time_to_seconds
|
79
|
-
m = /(?:(\d*)h)?\s?(?:(\d*)?m)?\s?(?:(\d*)?s)?/.match(
|
70
|
+
def human_time_to_seconds(time)
|
71
|
+
m = /(?:(\d*)h)?\s?(?:(\d*)?m)?\s?(?:(\d*)?s)?/.match(time)
|
80
72
|
h = ((m[1].to_i || 0) * 60) * 60
|
81
73
|
mi = (m[2].to_i || 0) * 60
|
82
74
|
s = (m[3].to_i || 0)
|
data/lib/authentic/validator.rb
CHANGED
@@ -5,55 +5,16 @@ require 'authentic/key_manager'
|
|
5
5
|
|
6
6
|
# Public: proper validation of JWTs against JWKs.
|
7
7
|
module Authentic
|
8
|
-
# Public: validate JWTs against JWKs using iss whitelist in an environment variable.
|
9
|
-
#
|
10
|
-
# token - raw JWT.
|
11
|
-
# opts - Optionally pass configuration options.
|
12
|
-
#
|
13
|
-
# Returns boolean.
|
14
|
-
def self.valid?(token, opts = {})
|
15
|
-
Validator.configure(opts) unless opts.empty?
|
16
|
-
Validator.new.valid?(token)
|
17
|
-
end
|
18
|
-
|
19
|
-
# Public: uses environment variable for iss whitelist and validates JWT,
|
20
|
-
# raises an error for invalid JWTs, errors requesting JWKs, the lack of valid JWKs, or non white listed ISS.
|
21
|
-
#
|
22
|
-
# token - raw JWT.
|
23
|
-
# opts - Optionally pass configuration options.
|
24
|
-
#
|
25
|
-
# Returns nothing.
|
26
|
-
def self.ensure_valid(token, opts = {})
|
27
|
-
Validator.configure(opts) unless opts.empty?
|
28
|
-
Validator.new.ensure_valid(token)
|
29
|
-
end
|
30
|
-
|
31
8
|
# Public: validates JWTs against JWKs.
|
32
9
|
class Validator
|
33
|
-
|
34
|
-
@@iss_whitelist = []
|
10
|
+
attr_reader :iss_whitelist, :manager, :opts
|
35
11
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
#
|
40
|
-
# Returns nothing.
|
41
|
-
def self.configure(opts)
|
42
|
-
@@iss_whitelist = opts[:iss_whitelist]
|
43
|
-
@@manager.cache_max_age(opts.fetch(:cache_max_age, '10h'))
|
44
|
-
end
|
45
|
-
|
46
|
-
def initialize
|
47
|
-
# Default iss whitelist if it is empty
|
48
|
-
@@iss_whitelist = @@iss_whitelist&.empty? ? ENV['ISS_WHITELIST']&.split('|') : @@iss_whitelist
|
49
|
-
|
50
|
-
valid_opts = !@@iss_whitelist&.empty?
|
51
|
-
raise IncompleteOptions unless valid_opts
|
52
|
-
end
|
12
|
+
def initialize(options = {})
|
13
|
+
@iss_whitelist = options.fetch(:iss_whitelist) { [] }
|
14
|
+
raise IncompleteOptions if iss_whitelist.empty?
|
53
15
|
|
54
|
-
|
55
|
-
|
56
|
-
@@manager.store.reset_all
|
16
|
+
max_age = options.fetch(:cache_max_age) { '10h' }
|
17
|
+
@manager = options.fetch(:key_manager) { KeyManager.new(max_age) }
|
57
18
|
end
|
58
19
|
|
59
20
|
# Public: validates JWT, returns true if valid, false if not.
|
@@ -62,7 +23,7 @@ module Authentic
|
|
62
23
|
#
|
63
24
|
# Returns boolean.
|
64
25
|
def valid?(token)
|
65
|
-
ensure_valid
|
26
|
+
ensure_valid(token)
|
66
27
|
true
|
67
28
|
rescue InvalidToken, InvalidKey, RequestError
|
68
29
|
false
|
@@ -75,16 +36,16 @@ module Authentic
|
|
75
36
|
#
|
76
37
|
# Returns nothing.
|
77
38
|
def ensure_valid(token)
|
78
|
-
jwt = decode_jwt
|
39
|
+
jwt = decode_jwt(token)
|
79
40
|
|
80
41
|
begin
|
81
|
-
key =
|
42
|
+
key = manager.get(jwt)
|
82
43
|
|
83
44
|
# Slightly more accurate to raise a key error here for nil key,
|
84
45
|
# rather then verify raising an error that would lead to InvalidToken
|
85
46
|
raise InvalidKey, 'invalid JWK' if key.nil?
|
86
47
|
|
87
|
-
jwt.verify!
|
48
|
+
jwt.verify!(key)
|
88
49
|
rescue JSON::JWT::UnexpectedAlgorithm, JSON::JWT::VerificationFailed
|
89
50
|
raise InvalidToken, 'failed to validate token against JWK'
|
90
51
|
rescue OpenSSL::PKey::PKeyError
|
@@ -101,7 +62,7 @@ module Authentic
|
|
101
62
|
raise InvalidToken, 'invalid nil JWT provided' unless token
|
102
63
|
|
103
64
|
JSON::JWT.decode(token, :skip_verification).tap do |jwt|
|
104
|
-
raise InvalidToken, 'JWT iss was not located in provided whitelist' unless
|
65
|
+
raise InvalidToken, 'JWT iss was not located in provided whitelist' unless iss_whitelist.include?(jwt[:iss])
|
105
66
|
end
|
106
67
|
rescue JSON::JWT::InvalidFormat
|
107
68
|
raise InvalidToken, 'invalid JWT format'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authentic-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Articulate
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-01-
|
12
|
+
date: 2019-01-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json-jwt
|