keratin-authn 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +21 -1
- data/keratin-authn.gemspec +1 -1
- data/lib/keratin/authn.rb +20 -5
- data/lib/keratin/authn/id_token_verifier.rb +3 -5
- data/lib/keratin/authn/mock_signature_verifier.rb +7 -0
- data/lib/keratin/authn/remote_signature_verifier.rb +19 -0
- data/lib/keratin/authn/test/helpers.rb +1 -24
- data/lib/keratin/authn/version.rb +1 -1
- metadata +18 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f56c448de089a50cd7d4ee112f5238cab39146e
|
4
|
+
data.tar.gz: 4e4b9953cb86e8a1ea827d5ea9e861578260effd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf79c26b1b0dd270c93fcbb708cbc7edf8931355555e69c069f6987ae577968844655ab221450198ccef76e71bb57a3c94233450da592327deb7f9d7c76b4f2d
|
7
|
+
data.tar.gz: c6c7f30a6799367f31a67c3b17eee21e50a04e9b5bb6bb38aec03482e0aca3da9ceb67c64ec0e29643e45a4e8e01c29b1295f603a1b6cfc54aa0f10161a31ab3
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -100,7 +100,27 @@ class SessionsController
|
|
100
100
|
end
|
101
101
|
```
|
102
102
|
|
103
|
-
##
|
103
|
+
## Testing Your App
|
104
|
+
|
105
|
+
AuthN provides helpers for working with tokens in your application's controller and integration tests.
|
106
|
+
|
107
|
+
In your `test/test_helper.rb` or equivalent:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# Configuring AuthN to use the MockSignatureVerifier will stop your tests from attempting to connect
|
111
|
+
# to the remote issuer during tests.
|
112
|
+
Keratin::AuthN.signature_verifier = Keratin::AuthN::MockSignatureVerifier.new
|
113
|
+
|
114
|
+
# Including the Test::Helpers module grants access to `id_token_for(user.account_id)`, so that you
|
115
|
+
# can test your system with real tokens.
|
116
|
+
module ActionDispatch
|
117
|
+
class IntegrationTest
|
118
|
+
include Keratin::AuthN::Test::Helpers
|
119
|
+
end
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
## Developing AuthN
|
104
124
|
|
105
125
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
106
126
|
|
data/keratin-authn.gemspec
CHANGED
@@ -30,7 +30,6 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.require_paths = ["lib"]
|
31
31
|
|
32
32
|
spec.add_dependency "json-jwt"
|
33
|
-
spec.add_dependency "webmock"
|
34
33
|
spec.add_dependency "lru_redux"
|
35
34
|
|
36
35
|
spec.add_development_dependency "bundler", "~> 1.13"
|
@@ -38,4 +37,5 @@ Gem::Specification.new do |spec|
|
|
38
37
|
spec.add_development_dependency "minitest", "~> 5.0"
|
39
38
|
spec.add_development_dependency "timecop"
|
40
39
|
spec.add_development_dependency "byebug"
|
40
|
+
spec.add_development_dependency "webmock"
|
41
41
|
end
|
data/lib/keratin/authn.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require_relative 'authn/version'
|
2
2
|
require_relative 'authn/engine' if defined?(Rails)
|
3
3
|
require_relative 'authn/id_token_verifier'
|
4
|
+
require_relative 'authn/remote_signature_verifier'
|
5
|
+
require_relative 'authn/mock_signature_verifier'
|
4
6
|
require_relative 'authn/issuer'
|
5
7
|
|
6
8
|
require 'lru_redux'
|
@@ -41,17 +43,30 @@ module Keratin
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
+
# The default strategy for signature verification will find the JWT's issuer, fetch the JWKs
|
47
|
+
# from that server, choose the correct key by id, and finally verify the JWT. The keys are
|
48
|
+
# then cached in memory to reduce network traffic.
|
49
|
+
def self.signature_verifier
|
50
|
+
@verifier ||= RemoteSignatureVerifier.new(
|
51
|
+
LruRedux::TTL::ThreadSafeCache.new(25, config.keychain_ttl)
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
# If the default strategy is not desired (as in host application tests), different strategies
|
56
|
+
# may be specified here. The strategy must define a `verify(jwt)` method.
|
57
|
+
def self.signature_verifier=(val)
|
58
|
+
if val.respond_to?(:verify) && val.method(:verify).arity == 1
|
59
|
+
@verifier = val
|
60
|
+
else
|
61
|
+
raise ArgumentError.new("Please ensure that your signature verifier has been instantiated and implements `def verify(jwt)`.")
|
62
|
+
end
|
46
63
|
end
|
47
64
|
|
48
65
|
class << self
|
49
66
|
# safely fetches a subject from the id token after checking relevant claims and
|
50
67
|
# verifying the signature.
|
51
|
-
#
|
52
|
-
# this may involve HTTP requests to fetch the issuer's configuration and JWKs.
|
53
68
|
def subject_from(id_token)
|
54
|
-
verifier = IDTokenVerifier.new(id_token,
|
69
|
+
verifier = IDTokenVerifier.new(id_token, signature_verifier)
|
55
70
|
verifier.subject if verifier.verified?
|
56
71
|
end
|
57
72
|
|
@@ -2,9 +2,9 @@ require 'uri'
|
|
2
2
|
|
3
3
|
module Keratin::AuthN
|
4
4
|
class IDTokenVerifier
|
5
|
-
def initialize(str,
|
5
|
+
def initialize(str, signature_verifier)
|
6
6
|
@id_token = str
|
7
|
-
@
|
7
|
+
@signature_verifier = signature_verifier
|
8
8
|
@time = Time.now.to_i
|
9
9
|
end
|
10
10
|
|
@@ -35,9 +35,7 @@ module Keratin::AuthN
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def token_intact?
|
38
|
-
|
39
|
-
rescue JSON::JWT::VerificationFailed, JSON::JWT::UnexpectedAlgorithm
|
40
|
-
false
|
38
|
+
@signature_verifier.verify(jwt)
|
41
39
|
end
|
42
40
|
|
43
41
|
private def jwt
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Keratin::AuthN
|
2
|
+
class RemoteSignatureVerifier
|
3
|
+
attr_reader :keychain
|
4
|
+
|
5
|
+
def initialize(keychain)
|
6
|
+
@keychain = keychain
|
7
|
+
end
|
8
|
+
|
9
|
+
def verify(jwt)
|
10
|
+
jwt.verify!(key(jwt['iss'], jwt.kid))
|
11
|
+
rescue JSON::JWT::VerificationFailed, JSON::JWT::UnexpectedAlgorithm
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
private def key(issuer, kid)
|
16
|
+
keychain.getset(kid){ Issuer.new(issuer).signing_key(kid) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'webmock/minitest'
|
2
|
-
|
3
1
|
module Keratin::AuthN
|
4
2
|
module Test
|
5
3
|
module Helpers
|
@@ -16,33 +14,12 @@ module Keratin::AuthN
|
|
16
14
|
).sign(jws_keypair.to_jwk, JWS_ALGORITHM).to_s
|
17
15
|
end
|
18
16
|
|
19
|
-
# a temporary RSA key for
|
17
|
+
# a temporary RSA key for the test suite.
|
20
18
|
#
|
21
19
|
# generates the smallest (fastest) key possible for RS256
|
22
20
|
private def jws_keypair
|
23
21
|
@keypair ||= OpenSSL::PKey::RSA.new(512)
|
24
22
|
end
|
25
|
-
|
26
|
-
# stubs the endpoints necessary to validate a signed JWT
|
27
|
-
private def stub_auth_server(issuer: Keratin::AuthN.config.issuer, keypair: jws_keypair)
|
28
|
-
Keratin::AuthN.keychain.clear
|
29
|
-
stub_request(:get, "#{issuer}/configuration").to_return(
|
30
|
-
status: 200,
|
31
|
-
body: {'jwks_uri' => "#{issuer}/jwks"}.to_json
|
32
|
-
)
|
33
|
-
stub_request(:get, "#{issuer}/jwks").to_return(
|
34
|
-
status: 200,
|
35
|
-
body: {
|
36
|
-
keys: [
|
37
|
-
keypair.public_key.to_jwk.slice(:kty, :kid, :e, :n).merge(
|
38
|
-
use: 'sig',
|
39
|
-
alg: JWS_ALGORITHM
|
40
|
-
)
|
41
|
-
]
|
42
|
-
}.to_json
|
43
|
-
)
|
44
|
-
end
|
45
|
-
|
46
23
|
end
|
47
24
|
end
|
48
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keratin-authn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lance Ivy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-jwt
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: webmock
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: lru_redux
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +108,20 @@ dependencies:
|
|
122
108
|
- - ">="
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: webmock
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
125
|
description:
|
126
126
|
email:
|
127
127
|
- lance@cainlevy.net
|
@@ -143,6 +143,8 @@ files:
|
|
143
143
|
- lib/keratin/authn/engine.rb
|
144
144
|
- lib/keratin/authn/id_token_verifier.rb
|
145
145
|
- lib/keratin/authn/issuer.rb
|
146
|
+
- lib/keratin/authn/mock_signature_verifier.rb
|
147
|
+
- lib/keratin/authn/remote_signature_verifier.rb
|
146
148
|
- lib/keratin/authn/test/helpers.rb
|
147
149
|
- lib/keratin/authn/testing.rb
|
148
150
|
- lib/keratin/authn/version.rb
|