keratin-authn 0.3.0 → 0.3.1

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
  SHA1:
3
- metadata.gz: 2f45b125d67113d0774cbad89d9267547e3b7e31
4
- data.tar.gz: de9f914409394e534f6fe8d9240fe0f4edb0c441
3
+ metadata.gz: 4f56c448de089a50cd7d4ee112f5238cab39146e
4
+ data.tar.gz: 4e4b9953cb86e8a1ea827d5ea9e861578260effd
5
5
  SHA512:
6
- metadata.gz: 164fd93bf93e7ccad0f9d005ea81fcc09e78bdb79bccb8a8b55f4776101631bdbc14d0b2a0d4f9347c0f0e322a1e45fad3c88d3f243b2bb9c561995380b17859
7
- data.tar.gz: a45bbfebe1d9bad1c0a5538cc8d679e5a7ee4ec3be78897a2c740c070bfae0ff89efdf8e1518d7b5c786d4940db6589aff7604f1b416474d068922616fbc43e3
6
+ metadata.gz: cf79c26b1b0dd270c93fcbb708cbc7edf8931355555e69c069f6987ae577968844655ab221450198ccef76e71bb57a3c94233450da592327deb7f9d7c76b4f2d
7
+ data.tar.gz: c6c7f30a6799367f31a67c3b17eee21e50a04e9b5bb6bb38aec03482e0aca3da9ceb67c64ec0e29643e45a4e8e01c29b1295f603a1b6cfc54aa0f10161a31ab3
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in auth-rb.gemspec
3
+ # Specify your gem's dependencies in keratin-authn.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -100,7 +100,27 @@ class SessionsController
100
100
  end
101
101
  ```
102
102
 
103
- ## Development
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
 
@@ -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
@@ -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
- def self.keychain
45
- @keychain ||= LruRedux::TTL::ThreadSafeCache.new(25, config.keychain_ttl)
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, keychain)
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, keychain)
5
+ def initialize(str, signature_verifier)
6
6
  @id_token = str
7
- @keychain = keychain
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
- jwt.verify!(@keychain.getset(jwt.kid){ Issuer.new(jwt['iss']).signing_key(jwt.kid) })
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,7 @@
1
+ module Keratin::AuthN
2
+ class MockSignatureVerifier
3
+ def verify(jwt)
4
+ true
5
+ end
6
+ end
7
+ end
@@ -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 our test suite.
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
@@ -1,5 +1,5 @@
1
1
  module Keratin
2
2
  module AuthN
3
- VERSION = "0.3.0"
3
+ VERSION = "0.3.1"
4
4
  end
5
5
  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.0
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-01-27 00:00:00.000000000 Z
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